Swiftのブロック(animateWithDuration:animations:completion :)


102

Swiftでブロックを機能させるのに問題があります。これが機能した例です(完了ブロックなし)。

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

または、末尾のクロージャーなし:

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

しかし、完了ブロックを追加しようとすると、機能しません。

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

オートコンプリートは私に与えますcompletion: ((Bool) -> Void)?が、それを動作させる方法はわかりません。末尾のクロージャでも試しましたが、同じエラーが発生しました:

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

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#>
})

私は完了ブロックの末尾クロージャーを明確にしていないと思うので使用しませんが、気に入った場合は以下のTrevorの答えを見ることができます


1
「オートコンプリートは私に完了を与えます:((Bool)-> Void)?しかし、それをどのように機能させるかはわかりません」まさにそれが言うこと。これはBoolを受け取り、Voidを返すブロックでなければなりません。
マット

((Bool)-> Void)をどうやって知るのですか?は何ですか?これは、BOOLが終了したことを知る前にObjCで使用したことがあるので。しかし、迅速なコーダーはどうやって知るのでしょうか?
Malhal 2014年

回答:


202

animateWithDurationのcompletionパラメータは、1つのブールパラメータを取るブロックを取ります。Obj Cブロックのように、Swiftでは、クロージャーが取るパラメーターを指定する必要があります。

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

ここで重要な部分は(value: Bool) inです。これは、このクロージャーが 'value'というラベルの付いたBoolを取り、voidを返すことをコンパイラーに伝えます。

参考までに、ブール値を返すクロージャーを作成する場合、構文は次のようになります。

{(value: Bool) -> bool in
    //your stuff
}

$0最初の引数にを使用して解決することもできます。ブロック内の変数を使用するだけで、コンパイラはブロックが引数を受け入れることを認識します。
2015年

1
dat完了ブロック構文:(
Chris Allinson

41

完了は正しく、クロージャはBoolパラメータを受け入れる必要があります:(Bool) -> ()。試す

UIView.animate(withDuration: 0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { finished in
    self.blurBg.hidden = true
})

2
このバージョン正しいことは注目に値します。推論できるため、完全なタイプを書き出す必要はありません。そのため、ここで説明するように、必要なのはクロージャーパラメーターを指定することだけです。
チャック

29

inキーワードとともにアンダースコアを単独で使用すると、入力は無視されます

スウィフト2

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

スイフト3、4、5

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

8

上記の受け入れられた答えに基づいて上記の私の解決策があります。ビューがフェードアウトし、ほとんど見えなくなると非表示になります。

スウィフト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
    })   
}

スイフト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
    })
}

4

これで、これはコンパイルされます

スウィフト2

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

スイフト3、4、5

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

Bool領域をアンダースコアにした理由は、その値を使用しないためです。必要な場合は、(_)を(value:Bool)に置き換えることができます。


1

これを変数に入れて、状況に応じてさまざまな方法でアニメーション化したい場合があります。そのために必要な

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

または、同じように詳細を使用することもできます。

 let completionBlock = { (_:Bool) in 
 }

しかし、いずれにしても、Boolどこかを示さなければなりません。


0

SWIFT 3.x + 4.x

更新を行い、処理を簡略化したいと思います。

以下の例は、viewゆっくりと非表示にしていて、完全に透明な場合に実装されています。親から削除しますview

ok変数は常にtrueアニメーションの終了とともに返されます。

    alpha = 1
    UIView.animate(withDuration: 0.5, animations: {
        self.alpha = 0
    }) { (ok) in
        print("Ended \(ok)")
        self.removeFromSuperview()
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.