Reputation: 16725
I have a UIViewController
and I'm refactoring it and I've bumped into a situation where I need to update it from another class. I know I need to use the delegate pattern, but I'm having a tough time finding an example that fits my situation (which I think it dirt simple).
ItemViewController
has a Timer
class that's instantiated. I'm trying to update an ItemViewController
label from the Timer
class.
On Timer
, I've done the following:
weak var delegate: TimerDelegate? // weak to avoid a retain cycle
func updateLabel(timeRemaining: Int) -> String {
return formatTimeInSeconds(timeRemaining) // another method w/in Timer
}
I declare the protocol
at the bottom of the Timer
class
protocol TimerDelegate: class {
func updateLabel(timeString: String) -> String
}
On ItemViewController
I have the following property declared:
@IBOutlet weak var timeValueLabel: UILabel?
I set it as a delegate of Timer
in viewDidLoad
as follows:
timer.delegate = self
What I'm trying to make happen is when updateLabel
is called on Timer
, I'd like to update timeValueLabel.text
on ItemViewController
. This is where I'm stuck...what next?
Upvotes: 0
Views: 140
Reputation: 72440
If your Timer
class assign from any where and you need to change the text of label you can use singleton object for that, create one singleton object with your Timer
class then use that object to set delegate like this way.
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)
}
}
Now you need to just set this delegate in your ItemViewController
like this.
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.
}
}
Upvotes: 2
Reputation: 613
I guess you should do:
func updateLabel(timeRemaining: Int) -> String {
let formattedTime = formatTimeInSeconds(timeRemaining)
delegate.updateLabel(formattedTime)
return formattedTime
}
And in the ItemViewController you should declare that the class follows the delegate and implement the declared method. Something like:
class ItemViewController: TimerDelegate {
...
func updateLabel(timeString: String) -> String {
...
}
}
Upvotes: 0