如何在viewDidAppear中只做一次?
我想检查粘贴板,并在出现视图时显示警报,如果它包含特定的值。 我可以将代码放入viewDidLoad
以确保它只调用一次,但问题是警报视图显示得太快。 我知道我可以设置一个计时器来推迟警报的外观,但是我认为这不是一个好的解决办法。
我检查了iOS 7的问题- viewDidLoad和viewDidAppear之间的差异 ,发现有一个步骤来检查视图是否存在。 所以我想知道有没有这样做?
更新:“只有一次”意味着视图控制器实例的生命周期 。
有一个标准的,内置的方法,你可以使用这个。
Objective-C的:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if ([self isBeingPresented] || [self isMovingToParentViewController]) { // Perform an action that will only be done once } }
Swift 3:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if self.isBeingPresented || self.isMovingToParentViewController { // Perform an action that will only be done once } }
当视图控制器首先被显示为模态显示的结果时,对isBeingPresented
的调用是真实的。 isMovingToParentViewController
在视图控制器首次被推入导航堆栈时为true。 视图控制器第一次出现时,其中一个是真实的。
无需处理BOOL
ivars或任何其他技巧来跟踪第一个电话。
rmaddy的答案是非常好的,但是它并不能解决问题,当视图控制器是导航控制器的根视图控制器和所有其他容器,不会将这些标志传递给它的子视图控制器。
所以这样的情况下我最好使用一个标志,并在以后使用。
@interface SomeViewController() { BOOL isfirstAppeareanceExecutionDone; } @end @implementation SomeViewController -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if(isfirstAppeareanceExecutionDone == NO) { // Do your stuff isfirstAppeareanceExecutionDone = YES; } } @end
如果我正确理解你的问题,你可以简单地设置一个BOOLvariables来识别viewDidAppear已经被调用,例如:
- (void)viewDidAppear { if (!self.viewHasBeenSet) { // <-- BOOL default value equals NO // Perform whatever code you'd like to perform // the first time viewDidAppear is called self.viewHasBeenSet = YES; } }
通过阅读其他评论(根据@rmaddy的回答),我知道这不是OP所要求的,而是因为这个问题的标题而来到这里的人:
extension UIViewController { var isPresentingForFirstTime: Bool { return isBeingPresented() || isMovingToParentViewController() } }
UPDATE
你应该在viewDidAppear
和viewWillAppear
使用这个方法。 (感谢@rmaddy)
更新2
此方法只适用于模态呈现的视图控制器和推视图控制器。 它不与一个childViewController工作。 使用didMoveToParentViewController
会更好的childViewControllers。
此解决scheme将在应用程序的整个生命周期内仅调用一次viewDidAppear
,即使您创build了视图控制器的多个对象,但一次后就不会调用该对象。 请参考上面的rmaddy的回答
您可以在 viewDidLoad
执行select器,也可以在viewDidAppear
使用dispatch_once_t
。如果你find更好的解决scheme,那么请与我分享。 这是我做的东西。
- (void)viewDidLoad { [super viewDidLoad]; [self performSelector:@selector(myMethod) withObject:nil afterDelay:2.0]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; static dispatch_once_t once; dispatch_once(&once, ^{ //your stuff [self myMethod]; }); }
您可以使用标志或设置标签来查看:
override func viewDidAppear(_ animated: Bool) { if view.tag == 0 { //Your view have appeared for the first time //do anything here you want to do //when next time your view will appear these lines will be skipped } view.tag = 1 }
你可以在ViewDidLoad方法中使用这个函数
performSelector:withObject:afterDelay:
它会在延迟后调用该函数。 所以你不必使用任何定制的计时器对象。 和一旦你可以使用
dispatch_once DCD block.Just performSelector在dispatch_once块中调用ViewDidLoad时只调用一次performSelector
希望能帮助到你
尝试设置一个BOOL值,当情况发生时调用它。
@interface AViewController : UIViewController @property(nonatomic) BOOL doSomeStuff; @end @implementation AViewController - (void) viewWillAppear:(BOOL)animated { if(doSomeStuff) { [self doSomeStuff]; doSomeStuff = NO; } }
在你启动AViewController实例的地方:
AddEventViewController *ad = [AddEventViewController new]; ad.doSomeStuff = YES;
不知道你为什么在ViewDidAppear
做到这ViewDidAppear
? 但是,如果你想doSomeStuff是私人的, soSomeStuff
只被调用一次,这里是通知的另一个解决scheme:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomeStuff) name:@"do_some_stuff" object:nil]; - (void) doSomeStuff {}
然后在某个地方发帖:
[[NSNotificationCenter defaultCenter] postNotificationName:@"do_some_stuff" object:nil];
if view.tag != 0 { // Not executed on First Instance // executed only when view did appear called after first time } view.tag = 1
- 第一次启动时,iCloud KeyValue存储未被识别
- C ++:如何在已经在iOS中的MFC应用程序中重用Encrypted Sqlite数据库
- 用不同的单元格types创build分组的UITableview
- PackageApplication今天停止与OS X 10.10(优胜美地)合作
- 如何在SWIFT中从UIView实例化ViewController
- 安装iOS应用程序,无需通过AppStore
- 更改未select的UITabBarController项目标题和背景图像的tintColor
- 如何使用iPhone应用程序发送RGB信号到BLE设备?
- didReceiveIncomingCall被调用,虽然它是一个未接来电