从非UIViewController类在UIViewController上设置标签文本

时间:2016-09-13 16:21:02

标签: ios swift delegates

我有UIViewController并且我正在重构它,我遇到了需要从另一个类更新它的情况。我知道我需要使用delegate pattern,但我很难找到一个适合我情况的例子(我觉得这很简单)。

ItemViewController有一个实例化的Timer类。我正在尝试更新ItemViewController类中的Timer标签。

Timer上,我完成了以下操作:

weak var delegate: TimerDelegate? // weak to avoid a retain cycle

func updateLabel(timeRemaining: Int) -> String {
    return formatTimeInSeconds(timeRemaining) // another method w/in Timer
}

我在protocol

的底部声明了Timer
protocol TimerDelegate: class {
    func updateLabel(timeString: String) -> String
}

ItemViewController上我声明了以下属性:

@IBOutlet weak var timeValueLabel: UILabel?

我将其设置为TimerviewDidLoad的委托,如下所示:

timer.delegate = self

我想要做的是在updateLabel上调用Timer时,我想更新timeValueLabel.text上的ItemViewController。这就是我被困的地方......下一步是什么?

2 个答案:

答案 0 :(得分:2)

如果你的Timer类从任何地方分配并且你需要更改标签的文本,你可以使用单例对象,用你的Timer类创建一个单例对象然后使用该对象来设置像这样委托。

class Timer {
    static let sharedInstance = Timer()
    weak var delegate: TimerDelegate?

    //Now use this delegate to call method.
    func updateLabel(timeRemaining: Int) -> String {
        delegate?.updateLabel(formatTimeInSeconds(timeRemaining) 
        return formatTimeInSeconds(timeRemaining) 
    }         
}

现在您需要在ItemViewController中设置此委托。

class ItemViewController: UIViewController, TimerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        Timer.sharedInstance.delegate = self
    }

    func updateLabel(timeString: String) -> String
        self.label.text = timeString
        return "" //return string that you want.
    }
}

答案 1 :(得分:0)

我想你应该这样做:

func updateLabel(timeRemaining: Int) -> String {
    let formattedTime = formatTimeInSeconds(timeRemaining)
    delegate.updateLabel(formattedTime)
    return formattedTime
}

在ItemViewController中,您应该声明该类遵循委托并实现声明的方法。类似的东西:

class ItemViewController: TimerDelegate {
    ...
    func updateLabel(timeString: String) -> String {
        ...
    }

}