在Swift

时间:2016-04-06 16:06:15

标签: ios swift methods

我有一个为新项目创建的通用NSObject动画类,我试图用新类重构一些旧项目。一切都很顺利,直到我找到一些完成块的动画,这就抛弃了我从视图控制器中删除过多冗余代码的计划。这就是我所拥有的......

Animator.swift

class Animator: NSObject {
    var control: UIControl? // Can accept everything that's a subclass of UIControl

    override init() {
        super.init()
    }

    // FIXME: figure out how to add a completion block as a parameter on a method call
    func animateControl(control: UIControl) {
        control.transform = CGAffineTransformMakeScale(0.75, 0.75)
        UIView.animateWithDuration(0.5,
                                   delay: 0,
                                   usingSpringWithDamping: 0.3,
                                   initialSpringVelocity: 5.0,
                                   options: UIViewAnimationOptions.AllowUserInteraction,
                                   animations: {
                                    control.transform = CGAffineTransformIdentity
        }) { (value: Bool) -> Void in
            // completion block
            // ** method as a parameter goes here? ** 
        }
    }
}

要使用它,而不是输入所有内容来设置按钮动画,我只需从MyViewController.swift

调用该类

MyViewController.swift

// Property declaration
let animator = Animator()

// Tie it to an IBAction
@IBAction func myButtonAction(sender: UIButton) {
    animator.animateControl(sender, methodIWantToRunAfterAnimateControlFinishes)
}

func methodIWantToRunAfterAnimateControlFinishes() {
    // Do Stuff
}

我如何向animateControl的初始化程序提供一个作为完成块运行的方法?我看了this(不是我的网站,但它是我的感受),但我无法让它发挥作用。

更新

我不得不与语法稍微搏斗一下,但这里的初始化代码让我超越了终点线:

func animateControl(control: UIControl, completion: (() -> Void)?) {
    control.transform = CGAffineTransformMakeScale(0.75, 0.75)
    UIView.animateWithDuration(0.5,
                               delay: 0,
                               usingSpringWithDamping: 0.3,
                               initialSpringVelocity: 5.0,
                               options: UIViewAnimationOptions.AllowUserInteraction,
                               animations: {
                                control.transform = CGAffineTransformIdentity
    }) { _ in
        // completion block
        completion?()
    }
}

这将处理带代码和nil完成块的完成块。

2 个答案:

答案 0 :(得分:3)

用作参数时非常简单的完成块如下所示:

onCompletion: (() -> Void)?

() -> Void可以为空?的原因是在Objective-C中可用。如果不需要,则不必将其括在括号中,也不要将其标记为可为空?

这将允许您传入一个不需要参数的函数,并且不返回任何参数。您可以将其添加到您的签名中,如下所示:

func animateControl(control: UIControl, onCompletion: (() -> Void)?)

如果要为其添加参数,请将它们添加到完成块的签名中:

func animateControl(control: UIControl, onCompletion: ((value: AnyObject) -> Void)?)

返回声明也是如此:

func animateControl(control: UIControl, onCompletion: ((value: AnyObject) -> AnyObject)?)

在您的功能签名中,您可以通过它的名称来呼叫它:

func animateControl(control: UIControl, onCompletion: ((value: AnyObject) -> Void)?) {
    //do stuff here
    onCompletion(obj)
}

答案 1 :(得分:1)

您可以添加这样的完成处理程序,您应该可以按照示例中的方式调用它。

func animateControl(control: UIControl, _ completion: (() -> ())? = nil) {
    control.transform = CGAffineTransformMakeScale(0.75, 0.75)
    UIView.animateWithDuration(0.5,
                               delay: 0,
                               usingSpringWithDamping: 0.3,
                               initialSpringVelocity: 5.0,
                               options: UIViewAnimationOptions.AllowUserInteraction,
                               animations: {
                                control.transform = CGAffineTransformIdentity
    }) { _ in
        completion?()
    }
}