如何使用回调闭包在控制器、检查器和返回之间传递数据 Swift

How to pass data between controller, checker and back using callback closures Swift

我是 Swift 的新手,这是我想问社区的第一个问题。 我有一个带有 textField、自定义按钮和标签的 viewcontroller,我还有一个单独的检查器来检查在 textField 中输入的单词是否正确。因此,当我按下按钮时,检查器正在检查并更改标签的颜色(如果 textfield.text 为空,则为绿色/红色/透明。我如何使用回调闭包来实现它?提前非常感谢!

这是我的 ViewController:

final class FeedViewController: UIViewController {

    private let checkTextField: UITextField = {
        let textField = MyCustomTextField(
            font: UIFont.systemFont(ofSize: 16),
            textColor: .black,
            backgroundColor: .white,
            placeholder: "Enter the word")
        
        return textField
    }()
    
    private lazy var checkButton: UIButton = {
        let button = MyCustomButton(
            title: "Check the word",
            titleColor: .white,
            backgroundColor: .systemGray,
            backgroundImage: nil) {

        }
        button.layer.cornerRadius = 6
        button.clipsToBounds = true
        return button
    }()
    
    private let colorLabel: UILabel = {
        let label = UILabel()
        label.alpha = 0
        label.toAutoLayout()
        return label
    }()
 
    private let checker: CheckTextField
    
    init(checker: CheckTextField) {
        self.checker = checker
        super .init(nibName: nil, bundle: nil)
    }

这是我的检查器:

class CheckTextField {
    
    private let correctWord = "correct word"
    
    func check( word: String) {
        

    }
}

我已经设法通过通知完成了这个任务,但是闭包对我来说太复杂了:(

闭包实际上是接收和调用它的方法的参数,因此如果您希望 check(word:) 在完成检查时调用一些闭包,您需要将其添加为参数:

func check(word: String, closure: ()->Void)

如果您想将参数传递给闭包,您也需要指定它:

func check(word: String, closure: (status: CheckResult)->Void)

我刚刚在这里补了CheckResult;我只需要一些可以用来传达检查结果的类型。它可以是一个枚举,例如:

enum CheckResult {
    case ok;
    case bad;
    case empty;
}

现在,在您的 check 函数中,您可以使用适当的值调用闭包,例如:closure(.ok)。更具体地说,让我们填写你的空函数:

class CheckTextField {
    private let correctWord = "apple"
    
    func check(word: String, closure: (_ status: CheckResult)->Void) {
        if word.count == 0 {
            closure(.empty)
        } else if word == correctWord {
            closure(.ok)
        } else {
            closure(.bad)
        }
    }
}

那么我们可以这样使用:

let checker = CheckTextField()

checker.check(word:"apple") { print([=14=]) }       // ok
checker.check(word:"pear") { print([=14=]) }        // bad
checker.check(word:"jackfruit") { print([=14=]) }   // bad
checker.check(word:"") { print([=14=]) }            // empty

您可以用代码替换 print([=19=]) 来设置标签颜色或您可能想要执行的任何其他操作。这很好,因为它会将有关您的视图的详细信息保留在 CheckTextField class.

之外

你可以在数据发送class中定义你的clousure如下

class DataSenderClass  {
var dataPassClousure:((String)->Void)?
func sendHere(){
    // i am invoking closure from here
    dataPassClousure?("hi i am data")
}

} 这里是 dataPassClousure 接受字符串作为参数(你可以根据你的选择进行调整或者也可以使用对象或者也可以将多个参数传递给你的闭包)是 sent/passed 给接收者class。 只需在您的数据接收器 class 中收听新数据,如下所示

class DataReceiverClass {
let senderObject = DataSenderClass()
func receiveHere() {
    //each time data change from sendHere function this closure invoke . perform your action
    senderObject.dataPassClousure = {arug1 in
        print("received data is \(arug1)")
    }
}

}