Закрытие iOS Swift Pass как собственность?

Скажем, у меня есть пользовательский UIView, который можно назвать MyCustomView. Внутри этого представления есть свойство UITextField. Предположим, моя цель - создать экземпляр MyCustomView и добавить его в какой-либо контроллер представления где-нибудь, и я хочу, чтобы этот контроллер представления мог обрабатывать действия, предпринятые в этом текстовом поле. Например, если я нажму "return" на клавиатуре в текстовом поле, я, возможно, захочу сделать какое-то действие - позвольте мне привести пример того, что я представляю с помощью кода objective-c psuedo:

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, так что каждый раз, когда я это делаю, мне не нужно будет добавлять все методы делегата в контроллеры представлений, к которым я добавляю, но, скорее, иметь единственную реализацию, которая просто независимо Я перехожу к нему... Как можно сделать это быстро?

Ответ 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!()

И вот тот же пример с использованием замыканий, которые могут принимать параметр 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!")