【问题标题】:iOS Swift Pass Closure as Property?iOS Swift 关闭作为属性?
【发布时间】:2014-08-03 12:26:32
【问题描述】:

假设我有一个自定义 UIView,我们称之为 MyCustomView。这个视图内部是一个 UITextField 属性。假设我的目标是能够创建 MyCustomView 的实例并将其添加到某个视图控制器中,并且我希望该视图控制器能够处理对该文本字段执行的操作。例如,如果我在文本字段中按键盘上的“return”,我可能想做一些动作 - 让我举个例子来说明我正在用一些 Objective-c 伪代码设想什么:

MyCustomView *myView = [[MyCustomView alloc] initWithFrame:CGRectMake(10,10,100,100)];
myView.textField.actionBlock = { /* do stuff here! */ }
[self.view addSubview:myView];

然后在 MyCustomView 类中,我会执行以下操作:

- (BOOL)textFieldShouldReturn:(UITextField *)textField  {
    self.actionBlock();
    return NO;
}

我希望 customView 成为 UITextFieldDelegate,这样每次执行此操作时,我都不必将所有委托方法添加到要添加到的视图控制器中,而只需一个实现即可whatever 我会传递给它...如何快速做到这一点?

【问题讨论】:

    标签: ios uitextfield closures swift uitextfielddelegate


    【解决方案1】:

    当然,您可以这样做。 Swift 有一流的函数,所以你可以做一些事情,比如像变量一样直接传递函数。请记住,函数本身实际上是幕后的闭包。这是一个基本示例:

    class MyClass {
        var theClosure: (() -> ())?
    
        init() {
            self.theClosure = aMethod
        }
    
        func aMethod() -> () {
            println("I'm here!!!")
        }
    }
    
    
    let instance = MyClass()
    if let theClosure = instance.theClosure {
        theClosure()
    }
    
    instance.theClosure = {
        println("Woo!")
    }
    instance.theClosure!()
    

    这是使用可以接受字符串参数的闭包的相同示例。

    class MyClass {
        var theClosure: ((someString: String) -> ())?
    
        init() {
            self.theClosure = aMethod
        }
    
        func aMethod(aString: String) -> () {
            println(aString)
        }
    }
    
    let instance = MyClass()
    if let theClosure = instance.theClosure {
        theClosure(someString: "I'm the first cool string")
    }
    
    instance.theClosure = {(theVerySameString: String) -> () in
        println(theVerySameString)
        someThingReturningBool()
    }
    instance.theClosure!(someString: "I'm a cool string!")
    

    【讨论】:

    • 非常好,感谢您提供的信息!我仍然在掌握展开选项等,所以我想知道如果我希望闭包是可选的会发生什么?使用此代码,如果没有提供闭包,它会崩溃。
    • @Mike 是的,对此感到抱歉。我已经在我的编辑中包含了展开。
    • 另外,另一个半相关的怪癖。假设我想在闭包内调用一个函数来执行某些操作并返回一个 Bool,但我不关心结果......似乎我必须做这样的事情 { var usedResult = self.doSomethingThatAlsoReturnsBool() }否则我得到“无法将表达式类型'()'转换为'Bool'”错误。有什么办法可以避免创建和分配未使用的结果?
    • @Mike 我不确定。我无法重现这种行为。
    • @Mike 当然可以。我已经在我的帖子中添加了一个例子。不过,我仍然不确定您到底为什么会收到该错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多