我在使用IBOutlets时遇到困难。我试图允许用户在表视图控制器(LoLAddGoalsTableViewController)中输入目标(称为nameOfRewardText),然后当他们单击“完成”时,将该目标显示在另一个视图控制器中的名为“ currentGoalTextField”的标签中(LoLGoalViewController)。我一直在尝试使用Save segue来实现此目的,但是建议使用带有委托的协议(Updating text in ViewController using Save function)。现在,我已经用协议和委托替换了保存命令,输入的“ nameOfRewardText”文本未显示在“ currentGoalTextField”标签中,我怀疑是因为IBOutlets不再正确地绑在一起了。我已附上以下奥特莱斯的代码和屏幕截图,以试图阐明我的位置。有谁知道我该如何修复IBOutlets,或者是否需要添加其他东西才能使它正常工作?我删除了将nameOfRewardText.text分配为Goal.goalText的行,因此我认为nameOfRewardText没有分配给var目标?也许我为此文本使用了太多名称(nameOfRewardText,goalText和currentGoalTextField),这使事情变得复杂了吗?任何帮助都将不胜感激,因为我对此很陌生!谢谢大家!

这是结构目标:

import UIKit

struct Goal {
    var goalText: String
    var pointsToCompleteGoal: Int
    var pointsEarnedTowardsGoal: Int
    var repeatGoal: Bool

    init(goalText: String, pointsToCompleteGoal: Int, pointsEarnedTowardsGoal: Int, repeatGoal: Bool = false) { //Made String non-optional. If issue later, can revert.
        self.goalText = goalText
        self.pointsToCompleteGoal = pointsToCompleteGoal
        self.pointsEarnedTowardsGoal = pointsEarnedTowardsGoal
        self.repeatGoal = repeatGoal
    }
}


这是公共协议:

import Foundation
import UIKit

protocol GoalDelegate: class {
    func passGoal(_ goal: Goal?)
}


这是创建委托的地方,您可以看到,我将nameOfRewardText.text分配为Goal.goalText的语句现在消失了:

import UIKit

class AddGoalsTableViewController: UITableViewController {

    var goal:Goal?
    var delegate: GoalDelegate?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// HASHED OUT THE BELOW BECAUSE REPLACING WITH DELEGATE:
//        if segue.identifier == "SaveGoal" {
//            let pointsNeededInt = Int(pointsNeededText.text!)
//            let pointsEarnedInt = Int(goalProgressText.text!)
//            goal = Goal(goalText: nameOfRewardText.text!, pointsToCompleteGoal: pointsNeededInt!, pointsEarnedTowardsGoal: pointsEarnedInt!)
//        }

        if let secondViewController = segue.destination as? LoLGoalViewController{
            delegate = secondViewController
            delegate?.passGoal(goal)
        }
    }

    @IBOutlet var goalTableTitleText : UILabel!
    @IBOutlet weak var goalProgressText: UILabel!
    @IBOutlet weak var nameOfRewardText: UITextField!
    @IBOutlet weak var pointsNeededText: UITextField!
    @IBOutlet weak var repeatSwitch: UISwitch!


override func viewDidLoad() {
    super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


带有插座的AddGoalsTableViewController的屏幕截图:
ios - 协议(protocol)/代理中IBOutlet的困难-LMLPHP

在这里,我遵守协议并调用函数passGoal:

import UIKit

class LoLGoalViewController: UIViewController, GoalDelegate {

    @IBOutlet weak var currentGoalTextField: UILabel!

    func passGoal(_ goal: Goal?) {
        currentGoalTextField.text = goal?.goalText
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

extension LoLGoalViewController {

    @IBAction func cancelToLoLGoalViewController(_ segue: UIStoryboardSegue) {
    }
}


带插座的LoLGoalViewController的屏幕截图:
ios - 协议(protocol)/代理中IBOutlet的困难-LMLPHP

最佳答案

您的LoLGoalViewController视图控制器可能尚未完全加载所有的插座。在我对上一个问题的回答上,您可以在LolGoalViewController中声明另一个变量:

@IBOutlet weak var currentGoalTextField: UILabel!

var goalText: String = ""


passGoal方法中,将字符串设置为goalText变量,而不是标签的文本:

func passGoal(_ goal: Goal?) {
    goalText = goal?.goalText
}


最后,在viewDidLoadLolGoalViewController中,将标签文本设置为goalText

override func viewDidLoad() {
    super.viewDidLoad()

    currentGoalTextField.text = goalText
}

关于ios - 协议(protocol)/代理中IBOutlet的困难,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48632272/

10-08 20:50