I have an NSTimer
that runs every 10 seconds and is kicked off from LandingController.m. It continues to run as you go to other views in the application. I want to be able to (when a certain condition is met within that timer) update a label field from another view GuardMenu.m The label I want to update is called CurrentZone.text and I want to update it from value "N" to value "Y."
Here's my timer on LandingController.m
self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:@selector(checkForMessages)
userInfo:nil
repeats:YES];
Which calls this on LandingController.m
- (void)checkForMessages
{
if ( //some condition here ){
//update CurrentZone.text label in GuardMenu view and set equal to "Y"
} else {
//no need to update label in GuardMenu as it's currently equal to "N"
}
}
For this you should use KVO(Key Value Observing). There are lot of ways to pass notifications, but KVO is potentially much simpler. I suspect that Notification is used more often because you can do a ‘chain of responsibility’ for an event as opposed to just assigning an observer. However, just having an observer in a controller that can watch a particular property in another object and get notified of changes is a powerful and simple way to solve a whole class of problems.
Firstly set a public property in
LandingController
like "lablelText
" .Then add the observer once, when you create the LandingController view. Once you've added the observer, the observeValueForKeyPath:ofObject:change:context: method will be executed in GuardMenu, so you can do the update to the GuardMenu UI from there. You shouldn't need to do anything every time GuardMenu is about to appear.
In GuardMenu, you should probably create LandingController just before you are going to push LandingController onto the controller stack, presumably in the event handler for some action the user took. Immediately after you create LandingController, add the observer in GuardMenu with the correct
NSKeyValueObservingOption
value.If you just want to be notified whenever the public property "lablelText" in LandingController is changed, then try this:
LandingController
As an alternative for this you can use NSNotificationCeneter to pass notifications from one class to another for some event. For this you can check my detailed answer How to pass Notifications from one class to another for some event.
Hope it helps you.
Maybe you should describe which error you're getting. Is your
checkForMessages
method (not) firing? Use anNSLog()
message to check. Otherwise, check if theUILabel
you want to change is actually loaded into memory (i.e. is notnil
). Please also let us know if thecurrentZone.text
is part of the view hierarchy of theLandingController
or of another view controller.First create a NSNotification in your
init
method of GuardMenu classThen implement the notification's selector, this is where you will be changing your
CurrentZone
label text.Now in your
LandingViewController.m
-viewDidLoad
MethodStart the timer.
Now implement the
@selector
for the NSTimer,this is where you will be sending the notification back to the GuardMenu class
NOTE: the
NotificationName
should be the same.Sample Project Code Dropbox Link
You can use the
prepareForSegue
method to pass objects between view controllers in the storyboard. For example, to pass a string from the GreyViewController to the OrangeViewController, in GreyViewController.m you have:Then in the
viewDidLoad
of the other view controller, in the OrangeViewController.m, you can set the text of the label by doing the following:You can make use of notifications.
In GuardMenu class
init
register for custom notificationIn LandingController->checkForMessages method post the notification when condition is satisfied.
In GuardMenu class implement the notification callback selector
Hope it helps!
Amar.
Make sure that the label you are trying to edit is declared as a property in the appropriate view and properly synthesised. Also make sure it is connected in Interface Builder.
In
GuardMenu.h
@property (strong, nonatomic) IBOutlet UILabel *CurrentZone;
Also, in
LandingController.h
, importGuardMenu.h
:#import "GuardMenu.h"
You will now be able to access the label and its text property from
LandingController.h
using