从另一个视图更新文本标签

时间:2013-05-11 14:56:49

标签: ios objective-c nstimer

我有一个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"

        }


    }

7 个答案:

答案 0 :(得分:8)

首先在GuardMenu类的init方法中创建一个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;
}

然后实施通知的选择器,您将在此处更改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实施@selector 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应该相同。

Sample Project Code Dropbox Link

答案 1 :(得分:0)

您可以使用prepareForSegue方法在故事板中的视图控制器之间传递对象。例如,要将一个字符串从GreyViewController传递给OrangeViewController,在GreyViewController.m中你有:

- (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;

答案 2 :(得分:0)

也许你应该描述你得到的错误。您的checkForMessages方法(不)被解雇了吗?使用NSLog()消息进行检查。否则,检查您要更改的UILabel是否实际加载到内存中(即不是nil)。如果currentZone.textLandingController或其他视图控制器的视图层次结构的一部分,也请告诉我们。

答案 3 :(得分:0)

您可以使用通知。

在GuardMenu类init中注册自定义通知

[[NSNotificationCenter defaultCenter] addObserver:self 
                                      selector:@selector(receiveNotification:) 
                                      name:@"MessageChangeNotification" 
                                      object:nil];

在LandingController-> checkForMessages方法在满足条件时发布通知。

[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageChangeNotification" 
                                      object:nil];

在GuardMenu类中实现通知回调选择器

- (void) receiveNotification:(NSNotification *) notification
{

    if ([[notification name] isEqualToString:@"MessageChangeNotification"]) {
        NSLog (@"Successfully received the notification");
        //Change the label text here..
    }
}

希望它有所帮助!
阿玛尔。

答案 4 :(得分:0)

确保您尝试编辑的标签在适当的视图中声明为属性并正确合成。还要确保它在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"
   }
}

答案 5 :(得分:0)

为此,您应使用 KVO(键值观察)。有很多方法可以传递通知,但 KVO 可能更简单。我怀疑Notification的使用频率更高,因为你可以为一个事件做一个“责任链”,而不仅仅是指派一个观察者。但是,只需在控制器中拥有一个能够观察另一个对象中特定属性并获得更改通知的控制器,就可以解决一大类问题。

首先在LandingController中设置公共属性,例如“lablelText”。

然后在创建LandingController视图时添加一次观察者。一旦添加了观察者,将在GuardMenu中执行 observeValueForKeyPath:ofObject:change:context:方法,因此您可以从那里对GuardMenu UI进行更新。每次GuardMenu即将出现时,您都不需要做任何事情。

在GuardMenu中,您可能应该在将LandingController推送到控制器堆栈之前创建LandingController,可能是在用户采取某些操作的事件处理程序中。创建LandingController后,立即在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

作为替代方案,您可以使用 NSNotificationCeneter 将通知从一个类传递到另一个类以用于某些事件。 为此,您可以查看我的详细答案How to pass Notifications from one class to another for some event

希望它对你有所帮助。

答案 6 :(得分:0)

在GuardMenu类的初始化

中创建通知
[[NSNotificationCenter defaultCenter] addObserver:self 
                                  selector:@selector(receiveNotification:) 
                                  name:@"UpdateCurrentZoneNotification" 
                                  object:nil];

在LandingController中,

  • (无效)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"
    
    }
    

    }