【问题标题】:iOS Accessing views data from delegate without allocating a new viewiOS从委托访问视图数据而不分配新视图
【发布时间】:2012-06-29 07:56:20
【问题描述】:

我需要从应用程序的委托方法ApplicationDidEnterForeground 更改数据(标签)而不分配新视图。该视图称为“提醒”,因此我将其导入到委托中,并且只有在分配它时才能访问其数据(提醒 *anything = [提醒分配...等),但因为我想更改当前加载的视图我需要直接访问已经加载的视图。

一旦我的应用程序进入前台,我将如何从委托更改主视图的标签?

obs:我知道我可以在 -(void)ViewDidLoad-(void)ViewWillAppear 上执行此操作,但它不会解决我的问题,因为它不会更改标签,例如,如果用户通过通知框打开应用程序(手机锁定时的滑动图标)。在这种情况下,如果应用程序在后台打开,则不会调用上述方法。

我不知道我是否清楚,希望我是。先感谢您。

【问题讨论】:

    标签: iphone ios xcode delegates uilocalnotification


    【解决方案1】:

    如果您正在使用情节提要,则可以这样做以访问当前正在查看的视图

    - (void)applicationDidEnterBackground:(UIApplication *)application
    { 
    UINavigationController *a=_window.rootViewController;
    Reminder *rem = a.topViewController;
    rem.label.text=@"test";
    }
    

    如果不使用故事板

    当我创建以后需要访问的视图时,我将它们定义为一个属性,就像这样

    在 AppDelegate.h 上

    //@interface SIMCAppDelegate : UIResponder <..........>
    //{
    //Some variables here
    //}
    
    //Properties here
    @property (strong, nonatomic) Reminder *reminder;
    
    //Some method declaration here
    //eg: -(void) showSomething;
    

    在 AppDelegate.m 上

    //@implementation AppDelegate
    
    @synthesize reminder;
    

    所以当我像这样分配/初始化视图时

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    //codes before here
    
    self.reminder = [[Reminder alloc] init];
    self.reminder.label.text = @"OLD LABEL";
    //codes after here
    }
    

    在其他方法上分配后我将能够再次访问它,像这样

    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
    
    self.reminder.label.text = @"NEW LABEL";
    }
    

    【讨论】:

    • 感谢您的回答。我已经用这样的东西进行了测试,但为了以防万一,我又做了一次,并且完全按照你写的那样做。尽管如此,标签并没有改变。还有其他猜测吗?
    • 实际上,标签甚至没有显示“旧标签”。它只是保持空白。是的,我已经连接了情节提要中的所有内容,并且可以从 Reminder.m 内部更改标签......我只是无法在它之外更改它。
    • 当您在 applicationWillEnterForeground 设置断点时,它会在那里中断吗?顺便说一下 applicationWillEnterForeground != ApplicationDidEnterForeground 这是你的问题中所述
    • 如何从reminder.m 中更改标签?你调用的代码/方法是什么来改变它,所以我会有更多的想法
    • 出于测试目的,我只是将标签从提醒.m viewDidLoad 方法更改。 label.text = @“任何东西”。我已经删除了它以防止与委托方法发生冲突。有没有办法实时做事?就像,不依赖委托标准方法?例如,如果有通知到达,同时更改标签,而不是完全取决于应用程序状态?
    【解决方案2】:

    只需从您的 ApplicationDidEnterForeground: 方法发送通知,然后在要更新标签的那个类上接收它...就像这样..

    //Your ApplicationDidEnterForeground:
    [[NSNotificationCenter defaultCenter] postNotificationWithName:@"UpdateLabel" withObject:nill];
    

    并在其中添加观察者 viewDidLoad: 您要更新标签的控制器

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

    在同一个班级中制作了你的方法......

    - (void)updateLabel:(NSNotification *)notification{
        update label
    }
    

    【讨论】:

    • 这很好用!我不知道为什么没有人赞成这个。
    【解决方案3】:

    也许你可以试试下面的代码 -

    NSMutableArray *activeControllerArray =  [self.navigationController.viewControllers mutableCopy];
    for (int i = 0; i< [activeControllerArray count]; i++) {
        if ([[activeControllerArray objectAtIndex:i] isKindOfClass:[Reminder Class]) {
            Reminder *object = [activeControllerArray objectAtIndex:i];
    
            //Perform all the task here which you want.
    
            break; //Once found break the loop to do further processing.
        }
    }
    

    【讨论】:

    • 感谢您的回答@rishi。只是一个问题,Xcode 无法识别“self.navigationController”。还有什么我应该做的吗?
    • 你的应用代理包含导航控制器的属性?
    • 我现在创建了一个。 Xcode 中没有问题,但是当我在您的代码中设置断点时,应用程序正在跳过 if 语句。
    • 您可以尝试记录并检查那里是否存在任何视图控制器,可能是导航层次结构存在问题。
    • 创建一个 navigationController 是不够的。要使此代码正常工作,导航控制器必须是窗口的根控制器,并且必须通过它添加所有其他控制器。
    猜你喜欢
    • 2016-07-18
    • 2018-04-05
    • 1970-01-01
    • 2019-02-22
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多