UIBarButtonItem 在函数返回之前不会更新标题

Posted

技术标签:

【中文标题】UIBarButtonItem 在函数返回之前不会更新标题【英文标题】:UIBarButtonItem doesn't update title until after function returns 【发布时间】:2014-03-17 19:17:36 【问题描述】:

我正在创建一个从一个站点加载基于嗅探的数据库的应用程序,所有这些都是通过“onlineSetup”方法完成的。

由于此方法可能会卡住一段时间,我想将 statusText 设置为“正在连接”,以便用户知道他必须等待。问题是:在 onlineSetup 方法返回之前,'setTitle' 会被忽略,即使之后调用了 onlineSetup 方法。

- (void)modeSwitchChanged:(id)sender

if (self.modeSwitch.isOn)

    [self setStatusText:@"Buscando dados: YokaiAnimes" withColor:[UIColor blackColor]];
    if ([self.db onlineSetup]) [self setStatusText:[NSString stringWithFormat:@"Animes encontrados: %d",self.db.animes.count] withColor:[UIColor greenColor]];
    else
    
        [self.db offlineSetup];
        [self setStatusText:@"Falha: internte desconectada." withColor:[UIColor grayColor]];
        [self.modeSwitch setOn:false animated:true];
    

else

    [self.mainTableView setBackgroundColor:[UIColor whiteColor]];
    [self setStatusText:@"Buscando dados: Memória Interna" withColor:[UIColor blackColor]];
    [self.db offlineSetup];
    [self setStatusText:[NSString stringWithFormat:@"Animes encontrados: %d",self.db.animes.count] withColor:[UIColor redColor]];

[self.mainTableView reloadData];


- (void)setStatusText:(NSString*)t withColor:(UIColor*)c

[self.statusLabel setTitle:t];
[self.statusLabel setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:c,NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];

【问题讨论】:

【参考方案1】:

在所有代码完成运行之前,界面中不会发生任何事情。这就是 ios 的工作原理。因此,如果您希望立即更改界面,则需要离开主线程片刻,让 runloop 完成循环,然后再继续。

- (void)modeSwitchChanged:(id)sender 
    if (self.modeSwitch.isOn) 
        [self setStatusText:@"Buscando dados: YokaiAnimes" withColor:[UIColor blackColor]];
        dispatch_async(dispatch_get_main_queue(), ^
             // call onlineSetup here
        );
     // ...

确实,如果onlineSetup真的很耗时,你应该在后台线程(而不是dispatch_get_main_queue()),因为如果你占用主线程太久,你会被立即死亡惩罚(好吧,无论如何,您的应用程序都会)。但是当然最终你必须回到主线程来对界面进行任何进一步的更改。这就是 GCD 如此出色的原因。它使这种线程切换变得简单而安全。

事实上,如果你在做网络,你肯定应该使用异步网络。这样做的能力是内置在 iOS 中的;如果您故意进行同步网络,请立即停止并修复它。最后你会得到一个回调,然后你可以回到主线程。

【讨论】:

有关如何退出主线程并重新使用 GCD 的更多详细信息和示例,请参阅我的书:apeth.com/iOSBook/ch38.html#_grand_central_dispatch 并在此处查看我的讨论(在答案和 cmets 中)关于在继续之前离开主线程以让界面更新:***.com/a/22446912/341994 嘿伙计,感谢您的快速响应 :) 首先,我没有使用 GCD 的经验,所以我很难了解这个“调度”命令的实际作用。我应该在调度中包含整个 if-else 语句还是只包含 onlineSetup 调用? 我尝试从 dispatch_async 调用 onlineSetup 但我什么也没得到。未设置标签,代码正常执行。也许我做错了什么? 嘿@LucasSunsi,好吧,而不是dispatch_async,让我们使用dispatch_after 尝试它,并在此问题底部的代码中使用零长度延迟:***.com/q/22446722/341994

以上是关于UIBarButtonItem 在函数返回之前不会更新标题的主要内容,如果未能解决你的问题,请参考以下文章

添加到情节提要的 UIBarButtonItem 在运行时不会出现

Swift,与 UIBarButtonItem 混淆

如果在工具栏中点击,UIBarButtonItem 不会突出显示?

动态创建的 UIBarButtonItem 不会在点击时触发

iOS 14 在打开之前设置 UIBarButtonItem 菜单

如何在返回箭头中更改 UIBarButtonItem?