2014-06-13 72 views
11

比方說,我有一個自定義UIView,可以稱之爲MyCustomView。在這個視圖內是一個UITextField屬性。假設我的目標是能夠創建一個MyCustomView實例並將其添加到某個視圖控制器,並且我希望該視圖控制器能夠處理在該文本字段上採取的操作。例如,如果我打的文本字段中鍵盤上的「返回」,我可能需要做一些動作 - 讓我給什麼我有一些Objective-C的僞代碼設想的一個例子:作爲屬性的iOS Swift Pass關閉?

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所以每次我這樣做的時候,我不會有添加所有的委託方法給視圖控制器我將它添加到,而是有一個實現,只是做無論我傳遞給它......如何快速完成這個任務?

回答

35

當然,你可以這樣做。 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!() 

這裏是使用可以接受String參數的閉包的例子。

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!") 
+0

非常好,感謝您的信息!我仍然在理解可選擇的可選項,所以我想知道如果我想讓閉包成爲可選項會發生什麼?使用這段代碼,如果沒有提供閉包,它會崩潰。 – Mike

+0

@Mike耶對此感到抱歉。我在編輯中包含了展開的內容。 –

+0

另外,另一個quirk半相關。比方說,我想調用一個閉包中的函數來做一些事情,並返回一個Bool,但我不關心結果...似乎我必須做這樣的事情{var unusedResult = self.doSomethingThatAlsoReturnsBool()}否則我會得到「無法將表達式類型'()'轉換爲'Bool'」錯誤。任何方式,我可以避免創建和分配unusedResult? – Mike