如何在 Swift iOS 中使用 Closures 发回数据?

How to send back data using Closures in Swift iOS?

提问人:SwiftNewbie 提问时间:1/2/2023 更新时间:3/15/2023 访问量:164

问:

我正在按照本教程使用 Closures 发送回数据。https://betterprogramming.pub/5-ways-to-pass-data-between-view-controllers-18acb467f5ec

在本教程中,第 4 点是“闭包”。我有两个 VC,一个用于选择宠物 (FormsVC),一个用于显示选定的宠物 (ProfileVC)。

下面是 ProfileVC 的代码:

// ProfileVC

// MARK: - Set Fav Pet Name
    
    func setPetName(pet: String) {
        lblFavouritePet.text = pet
    }

// MARK: - Button Select Your Fav Pet Event

    @IBAction func btnSelectYourFavPet_Event(_ sender: UIButton) {
        
        let vc = FormsVC()
        
        self.present(vc, animated: true)
    }

以下是 FormsVC 的代码:

// FormsVC

// MARK: - Variable Declaration
    
    var favoritePet = String()

// MARK: - viewDidLoad Method

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpFormsVC()
        
    }

// MARK: - Set Up FormsVC
    
    func setUpFormsVC() {
       
        btnDog.titleLabel?.text = "Dog"
        btnCat.titleLabel?.text = "Cat"
        btnRabbit.titleLabel?.text = "Rabbit"
        btnBird.titleLabel?.text = "Bird"
        
    }

// MARK: - Button Selected Pet Event
    
    @IBAction func selectedPetEvent(_ sender: UIButton) {
        
        favoritePet = sender.titleLabel?.text ?? "Dog"
        
    }

// MARK: - Selected Pet Name
    
    func getFavoritePet() -> String {
        return favoritePet
    }

// MARK: - Button OK Event

    @IBAction func btnOk_Event(_ sender: UIButton) {
        
        let vc = ProfileVC()
        
        self.dismiss(animated: true, completion: {
            vc.setPetName(pet: self.getFavoritePet())
        })

// problem occurs when I dismiss FormsVC after selecting pet, the label displaying selected pet name (lblFavouritePet) throwing error of "Unexpectedly found nil while implicitly unwrapping an Optional value"
        
    }
}

当我在选择宠物后关闭 FormsVC 时出现问题,标签显示选定的宠物名称 (lblFavouritePet) 抛出错误“在隐式解开可选值时意外发现 nil”。我不知道为什么它被发现为零,因为我已经分配了所选宠物的 favoritePet 值。对不起这个愚蠢的问题,谁能帮我?

iOS Swift Closures 传递数据

评论

2赞 matt 1/2/2023
在不是现有 ProfileVC 的行中。请阅读 programmingios.net/dont-make-a-new-instance-by-mistakelet vc = ProfileVC()

答:

-1赞 Dhaval Patoliya 1/2/2023 #1

首先,您必须在要传递数据的地方声明闭包。

// FormsVC
// MARK: - Variable Declaration
let completion: ((String)->Void)? = nil

// MARK: - Button OK Event
@IBAction func btnOk_Event(_ sender: UIButton) {
    
    completion?(self.getFavoritePet())
    self.dismiss(animated: true)
}

第二部分是你必须编写代码来接收数据。

// ProfileVC
// MARK: - Button Select Your Fav Pet Event

@IBAction func btnSelectYourFavPet_Event(_ sender: UIButton) {
    
    let vc = FormsVC()
    vc.completion = { petName in
        self.setPetName(pet: petName)
    }

    self.present(vc, animated: true)
}

评论

0赞 SwiftNewbie 1/3/2023
这行得通!谢谢!只需一个更改即可完成:((String)->Void)?= nil,这应该是变量,而不是常量。再次感谢!
0赞 corscheg 1/3/2023 #2

如@matt所述,您应该使用呈现视图控制器,而不是创建新实例。在您使用的教程中,它已说明:

if let vc = presentingViewController as? Profile...

你的应用崩溃了,因为你使用了情节提要,并且是隐式解包的可选,因此,你应该从情节提要初始化它。但是您在不使用情节提要的情况下对其进行初始化,并且该属性仍然存在。lblFavoritePet@IBOutletnil

因此,不要创建新实例,请使用教程中所述的代码。

并遵循命名约定

评论

0赞 SwiftNewbie 1/3/2023
如果让 vc = presentingViewController as?轮廓。。。如果我写这一行,那么演示控制器不会被解雇!这就是为什么我写了 let vc = ProfileVC(),现在我知道这是错误的。但是如果让 vc = presentingViewController 作为?轮廓。。。在我的情况下也不起作用!