从另一个视图更新文本标签
我有一个NSTimer
,每10秒运行一次,并从LandingController.m中启动。 它继续运行,当你去应用程序中的其他视图。 我希望能够(当在该定时器内满足特定条件时)从另一个视图更新标签字段GuardMenu.m我想更新的标签名为CurrentZone.text,我想将它从值“N”更新为值“Y”。
这是我在LandingController.m上的计时器
self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(checkForMessages) userInfo:nil repeats:YES];
在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" } }
首先在GuardMenu类的init
方法中创build一个NSNotification
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"TextChangeNotification" object:nil]; } return self; }
然后实现通知的select器,这是你将要改变你的CurrentZone
标签文本的地方。
- (void)receiveNotification:(NSNotification *) notification { if ([[notification name] isEqualToString:@"TextChangeNotification"]) { NSLog (@"Change you label here"); self.lblCurrentZone.text = @"Y"; } }
现在在你的LandingViewController.m
-viewDidLoad
方法中
启动计时器。
self->msgTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(checkForMessages) userInfo:nil repeats:YES];
现在为NSTimer实现@select器, this is where you will be sending the notification back to the GuardMenu class
- (void)checkForMessages { NSString *strText = @"test"; if ([strText isEqualToString:@"test"]){ [[NSNotificationCenter defaultCenter] postNotificationName:@"TextChangeNotification" object:nil]; } else { } }
注: NotificationName
应该是相同的。
示例项目代码Dropbox链接
您可以使用prepareForSegue
方法在故事板中的视图控制器之间传递对象。 例如,要将GreyViewController中的string传递给GreyViewController.m中的OrangeViewController,您需要:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { OrangeViewController *orange = [segue destinationViewController]; orange.self.orangeString = @"text for orangeView"; }
然后在其他视图控制器的viewDidLoad
中,在OrangeViewController.m中,可以通过执行以下操作来设置标签的文本:
self.orangeLabel.text = self.orangeString;
也许你应该描述你得到的错误。 你的checkForMessages
方法(不)发射? 使用NSLog()
消息来检查。 否则,检查你想改变的UILabel
是否真的被加载到内存中(即不是nil
)。 如果currentZone.text
是LandingController
或其他视图控制器的视图层次结构的一部分,请告诉我们。
你可以使用通知。
在GuardMenu类init
注册中进行自定义通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"MessageChangeNotification" object:nil];
在LandingController-> checkForMessages方法中,当条件满足时发布通知。
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageChangeNotification" object:nil];
在GuardMenu类中实现通知callbackselect器
- (void) receiveNotification:(NSNotification *) notification { if ([[notification name] isEqualToString:@"MessageChangeNotification"]) { NSLog (@"Successfully received the notification"); //Change the label text here.. } }
希望能帮助到你!
阿马尔。
确保您正在尝试编辑的标签在适当的视图中被声明为属性并正确合成。 还要确保它在Interface Builder中连接。
在GuardMenu.h
@property (strong, nonatomic) IBOutlet UILabel *CurrentZone;
另外,在LandingController.h
,导入GuardMenu.h
:
#import "GuardMenu.h"
您现在可以使用LandingController.h
访问标签及其文本属性
-(void)checkForMessages { GuardMenu *guardMenu = [[GuardMenu alloc]init]; if (/* some condition here */) { //update CurrentZone.text label in GuardMenu view and set equal to "Y" guardMenu.CurrentZone.text = @"Y"; } else { //no need to update label in GuardMenu as it's currently equal to "N" } }
为此,您应该使用KVO(关键值观察) 。 有很多方法可以传递通知,但是KVO可能要简单得多。 我怀疑“通知”更经常被使用,因为你可以为一个事件做一个“ 责任链 ”,而不是只分配一个观察者。 然而,只要有一个观察者在一个控制器中,可以观察另一个对象中的特定属性并获得变化的通知,这是一个解决一整类问题的强大而简单的方法。
首先在LandingController
设置一个公共属性,如“ lablelText
”。
然后在创buildLandingController视图时添加一次观察者。 一旦添加了观察者, observingValueForKeyPath:ofObject:change:context:方法将在GuardMenu中执行,所以您可以从那里对GuardMenu UI进行更新。 每次GuardMenu即将出现时,您都不需要做任何事情。
在GuardMenu中,您应该在将LandingController推入控制器堆栈之前创buildLandingController,大概是在事件处理程序中用户执行了某些操作。 在创buildLandingController之后,立即在GuardMenu中添加具有正确NSKeyValueObservingOption
值的观察者。
如果您只是想在LandingController中的公共属性“lablelText”发生更改时收到通知,请尝试以下操作:
LandingController
@interface LandingController : UIViewController { } @property (strong, nonatomic) NSString* lablelText; - (void)checkForMessages; @end @implementation LandingController @synthesize lablelText; - (void)checkForMessages { if ( //some condition here ){ //update CurrentZone.text label in GuardMenu view and set equal to "Y" self.lablelText = @"Y"; } else { //no need to update label in GuardMenu as it's currently equal to "N" self.lablelText = @"N"; } } @end GuardMenu @interface GuardMenu : UIViewController { } @property (strong, nonatomic) IBOutlet UILabel* nameLabel; - (IBAction) methodToHandleEvent:(id)sender; @end @implementation GuardMenu - (IBAction) methodToHandleEvent:(id)sender{ LandingController* tempVC = [[LandingController alloc]init]; [tempVC addObserver:self forKeyPath:@"lablelText" options:NSKeyValueObservingOptionNew context:NULL]; [self.navigationController pushViewController:tempVC animated:YES]; } - (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { // Here you will be notified everytime lablelText changes if ([keyPath isEqual:@"lablelText"]) { NSString* changedName = [change objectForKey:NSKeyValueChangeNewKey]; // do something with the changedName - call a method or update the UI here self.nameLabel.text = changedName; } } @end
作为替代scheme,您可以使用NSNotificationCeneter将某个事件的通知从一个类传递到另一个类。 为此,您可以检查我的详细答案如何将某个事件的通知从一个类传递到另一个类 。
希望它可以帮助你。
在GuardMenu类的init中创build一个通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"UpdateCurrentZoneNotification" object:nil];
在LandingController中,
-
(void)checkForMessages {
if ( //some condition here ){ [[NSNotificationCenter defaultCenter] postNotificationName:@"UpdateCurrentZoneNotification" object:nil]; //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" }
}