Bloki w Swift (animateWithDuration: animations: complete :)

102

Mam problem z uruchomieniem bloków w Swift. Oto przykład, który zadziałał (bez bloku uzupełniania):

UIView.animateWithDuration(0.07) {
    self.someButton.alpha = 1
}

lub alternatywnie bez zamknięcia końcowego:

UIView.animateWithDuration(0.2, animations: {
    self.someButton.alpha = 1
})

ale kiedy spróbuję dodać blok uzupełniania, po prostu nie zadziała:

UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: {
    self.blurBg.hidden = true
})

Autouzupełnianie daje mi, completion: ((Bool) -> Void)?ale nie jestem pewien, jak to działa. Próbowano również z końcowym zamknięciem, ale wystąpił ten sam błąd:

! Could not find an overload for 'animateWithDuration that accepts the supplied arguments

Aktualizacja dla Swift 3/4:

// This is how I do regular animation blocks
UIView.animate(withDuration: 0.2) {
    <#code#>
}

// Or with a completion block
UIView.animate(withDuration: 0.2, animations: {
    <#code#>
}, completion: { _ in
    <#code#>
})

Nie używam końcowego zamknięcia dla bloku uzupełniania, ponieważ wydaje mi się, że brakuje mu jasności, ale jeśli ci się spodoba, możesz zobaczyć odpowiedź Trevora poniżej .

manolosavi
źródło
1
„Autouzupełnianie daje mi uzupełnienie: ((Bool) -> Void)? Ale nie wiem, jak to działa”. Dokładnie to, co mówi. To musi być blok, który przyjmuje wartość logiczną i zwraca Pustkę.
mat.
Skąd wiesz, co jest ((Bool) -> Void)? jest dla? Ponieważ użyłem tego w ObjC, zanim dowiedziałem się, że jest to BOOL zakończone. Ale skąd by to wiedział szybki programista?
malhal

Odpowiedzi:

202

parametr zakończenia w animateWithDuration przyjmuje blok, który przyjmuje jeden parametr boolowski. Szybko, podobnie jak w blokach Obj C, musisz określić parametry, które przyjmuje zamknięcie:

UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: {
    (value: Bool) in
    self.blurBg.hidden = true
})

Ważną częścią jest tutaj (value: Bool) in. To mówi kompilatorowi, że to zamknięcie przyjmuje wartość Bool oznaczoną jako „wartość” i zwraca wartość void.

Dla porównania, jeśli chcesz napisać zamknięcie, które zwróciło wartość logiczną, składnia byłaby taka

{(value: Bool) -> bool in
    //your stuff
}
Zaksoup
źródło
Można to również rozwiązać, używając $0jako pierwszego argumentu, po prostu używając zmiennej wewnątrz bloku, kompilator wykrywa, że ​​twój blok przyjmuje argument.
Może
1
Składnia bloku uzupełniania dat :(
Chris Allinson,
41

Zakończenie jest poprawna, zamknięcie musi zaakceptować Boolparametr: (Bool) -> (). Próbować

UIView.animate(withDuration: 0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { finished in
    self.blurBg.hidden = true
})
Nicholas H.
źródło
2
Warto zaznaczyć, że ta wersja jest poprawna. Nie musisz pisać pełnego typu, ponieważ można go wywnioskować, więc wystarczy wspomnieć o parametrze zamknięcia, jak wspomniano tutaj.
Chuck,
29

Samo podkreślenie obok insłowa kluczowego zignoruje wprowadzone dane

Szybki 2

UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { _ in
    self.blurBg.hidden = true
})

Swift 3, 4, 5

UIView.animate(withDuration: 0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { _ in
    self.blurBg.isHidden = true
})
Dan Greenfield
źródło
8

Jest moje rozwiązanie powyżej oparte na zaakceptowanej odpowiedzi powyżej. Znika widok i ukrywa go kiedyś prawie niewidoczny.

Szybki 2

func animateOut(view:UIView) {

    UIView.animateWithDuration (0.25, delay: 0.0, options: UIViewAnimationOptions.CurveLinear ,animations: {
        view.layer.opacity = 0.1
        }, completion: { _ in
            view.hidden = true
    })   
}

Swift 3, 4, 5

func animateOut(view: UIView) {

    UIView.animate(withDuration: 0.25, delay: 0.0, options: UIView.AnimationOptions.curveLinear ,animations: {
        view.layer.opacity = 0.1
    }, completion: { _ in
        view.isHidden = true
    })
}
Jaro
źródło
4

Proszę bardzo, to się skompiluje

Szybki 2

UIView.animateWithDuration(0.3, animations: {
    self.blurBg.alpha = 1
}, completion: {(_) -> Void in
    self.blurBg.hidden = true
})

Swift 3, 4, 5

UIView.animate(withDuration: 0.3, animations: {
    self.blurBg.alpha = 1
}, completion: {(_) -> Void in
    self.blurBg.isHidden = true
})

Powodem, dla którego uczyniłem obszar Bool podkreśleniem, jest to, że nie używasz tej wartości, jeśli jej potrzebujesz, możesz zamienić (_) na (wartość: Bool)

Kris Gellci
źródło
1

Czasami chcesz wrzucić to do zmiennej, aby animować ją na różne sposoby w zależności od sytuacji. Do tego potrzebujesz

 let completionBlock : (Bool) -> () = { _ in 
 }

Lub możesz użyć równie rozwlekłych:

 let completionBlock = { (_:Bool) in 
 }

Ale w każdym razie musisz Boolgdzieś wskazać .

Dan Rosenstark
źródło
0

SWIFT 3.x + 4.x

Chciałbym dokonać aktualizacji i uprościć wszystko.

Przykład poniżej jest zaimplementowany w każdym, viewgdy ukrywa się powoli i kiedy jest całkowicie przezroczysty; usuwa to samo z rodzicówview

okzmienna będzie zawsze zwracana truepo zakończeniu animacji.

    alpha = 1
    UIView.animate(withDuration: 0.5, animations: {
        self.alpha = 0
    }) { (ok) in
        print("Ended \(ok)")
        self.removeFromSuperview()
    }
Trevor
źródło