【问题标题】:UIApplicationDidBecomeActiveNotification and setRightBarButtonItem:animated:UIApplicationDidBecomeActiveNotification 和 setRightBarButtonItem:animated:
【发布时间】:2013-03-06 16:49:23
【问题描述】:

TL;DR 更新:基本上我需要延迟我的代码,直到 iOS 完成其“应用启动”动画。

我想在我的应用激活时为导航栏的内容制作动画。在我的控制器中,我订阅了UIApplicationDidBecomeActiveNotification 并使用setRightBarButtonItem:animated: 来执行更改。

问题是变化不是动画的。

我做了一些实验,发现如果我稍等片刻 ([NSThread sleepForTimeInterval:.3]),它的动画就没有任何问题。

这是一个演示问题的简单视图控制器:

@interface TESTViewController ()

@property (strong, nonatomic) IBOutlet UINavigationBar *navigationBar;

@end

@implementation TESTViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    UINavigationItem *item = [UINavigationItem new];
    UIBarButtonItem *oldItem = [[UIBarButtonItem alloc] initWithTitle:@"Old" style:UIBarButtonItemStyleBordered target:nil action:NULL];
    [item setRightBarButtonItem:oldItem];
    [[self navigationBar] setItems:@[item] animated:NO];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActiveNotificationAction:) name:UIApplicationDidBecomeActiveNotification object:nil];
}

- (void)applicationDidBecomeActiveNotificationAction:(NSNotification *)notification
{
    // [NSThread sleepForTimeInterval:.3];
    UIBarButtonItem *newItem = [[UIBarButtonItem alloc] initWithTitle:@"New" style:UIBarButtonItemStyleBordered target:nil action:NULL];
    [[[self navigationBar] items][0] setRightBarButtonItem:newItem animated:YES];
}

@end

我想找到一个比阻塞线程或在固定延迟后执行更改更好的解决方案。

【问题讨论】:

  • 应用程序在视图出现之前变为“活动” - 为什么不简单地将动画代码从 applicationDidBecomeActiveNotificationAction 移动到 viewDidAppear
  • @rokjarc 我很乐意。问题是当我切换回应用程序时没有调用viewDidAppear:。顺便说一句,viewDidAppear: 名称有点误导(请参阅stackoverflow.com/questions/5417318/…)。
  • 啊,是的。我知道我前段时间看到了一个解决方法。我相信它与UINavigationController 有关(即使它没有在视图层次结构中使用)。会尝试找到它。
  • @rokjarc 非常感谢,非常感谢!
  • 我过去曾通过使用 dispatch_async(到主队列)并在该块中执行动画来解决类似的问题。它不会增加可见的延迟,也不会阻塞任何线程。不过,可能不适用于您的具体情况。

标签: ios objective-c cocoa-touch uinavigationbar uiapplication


【解决方案1】:

只需在主队列上使用dispatch_after,而不是调用
+[NSThread sleepForTimeInterval:]类方法。

将您的动画作为一个块传递,它应该可以完美运行。

【讨论】:

  • 是的,这应该可以,因为更改将在稍后执行——这意味着在下一个更新周期。这只是一种解决方法,但由于这与内部实现有关,因此没有正确的方法这样做。
  • 这实际上不是一种解决方法;它确实比使用[NSThread sleepForTimeInterval:] 好得多,因为它不会阻塞 UI 线程。很多时候,在过渡方面,有必要稍微延迟一点以允许进程内动画完成,以便您的动画可以正确启动(并在正确的位置)。并且dispatch_after()(或[obj performSelector:withObject:afterDelay:])是在不阻塞的情况下执行此操作的方法。
【解决方案2】:

发布通知时,我不使用您的方法。

我用:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeButton) name:@"changeButton" object:nil]; 在接收端。

在发帖结束时,我打电话给 [[NSNotificationCenter defaultCenter] postNotificationName:@"changeButton" object:nil];

尝试将代码移动到方法中:

-(void)changeButton{

UIBarButtonItem *newItem = [[UIBarButtonItem alloc] initWithTitle:@"New" style:UIBarButtonItemStyleBordered target:nil action:NULL];

[[[self navigationBar] items][0] setRightBarButtonItem:newItem animated:YES];

}

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    您是否尝试过执行SelectorAfterDelay?

    试试这样的:

    - (void)applicationDidBecomeActiveNotificationAction:(NSNotification *)notification{
         [self performSelector:@selector(yourAnimationAction) withObject:nil afterDelay:1];
    }
    
    - (void)yourAnimationAction{
        //Set your NavAnimation here
        [self.navigationItem setRightBarButtonItem:theItem animated:TRUE];
    }
    

    只需更改延迟以适合您的应用唤醒延迟...也许这会生效?

    【讨论】:

      【解决方案4】:

      移动试试 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActiveNotificationAction:) name:UIApplicationDidBecomeActiveNotification object:nil];viewDidLoad: 方法。我认为对象在被触发时未注册为“UIApplicationDidBecomeActiveNotification”。

      【讨论】:

        【解决方案5】:

        只需在您的applicationDidBecomeActiveNotificationAction: 方法中手动调用viewDidAppear:。将您的动画代码放在viewDidAppear: 方法中。希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-25
          • 2011-02-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多