different addSubview behavior between iOS 4.3 and 5.0(viewWillAppear 不被调用)
2012-07-25 15:24
381 查看
这篇文章 说的很细 :
http://stackoverflow.com/questions/7830830/ios-different-addsubview-behavior-between-ios-4-3-and-5-0
http://stackoverflow.com/questions/7830830/ios-different-addsubview-behavior-between-ios-4-3-and-5-0
21 down vote favorite 16 | while coding in iOS 4.3 before, I found while add a view controller's view to another view with[superview addSubView:controller.view], the controller instance will not receive the -viewWillAppear/viewDidAppearmessage, than I found same issue in some thread in stack overflow. After that, I manually call -viewWillAppear/-viewDidAppearas needed. but, after upgrade to iOS 5.0, some frisky UIViewbehavior happened. Finally I found that in iOS 5, the [superview addSubView:controller.view], will send a -viewWillAppear/-viewDidAppearmessage to the controller instance automatically, plus my manually calls, there are two duplicated message each time the controller action its behavior. and I also found a similar issue: iOS 5 : -viewWillAppear is not called after dismissing the modal in iPad Now, the problem is, after search apple's documents, I didn't find any explicitly doc for diff about these issues. I even wonder if this is a guaranteed view life cycle behavior in iOS 5.0 . Does anyone fix similar issues or find some guidelines about these difference. cause I want to run my app both in 4.x & 5.x iOS. iphone ios ipad uiviewcontroller ios5-compatibility
| |||
|
6 Answers
activeoldestvotesup vote 18 down voteaccepted | In iOS 4 you had to manually call -viewWillAppear, -viewWillDisappear, etc. when adding or removing a view from your view hierarchy. These are called automatically in iOS 5 if the view is being added or removed from the window hierarchy. Fortunately, iOS 5 has a method in UIViewControllerthat you can override to revert the behaviour back to how it worked with iOS 4. Just add this to your UIViewController: -(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { return NO; } This is probably the easiest solution as long as you're supporting both iOS 4 and iOS 5. Once you drop support for iOS 4 you might consider modifying your code to use the newer approach when swapping views. Edit 5 February 2012 Apparently this function requires the child view controller be added to the main view controller using the addChildViewController:method. This method doesn't exist in iOS4, so you need to do something like this: if ([self respondsToSelector:@selector(addChildViewController:)] ) { [self addChildViewController:childViewController]; } Thanks to everyone who corrected me on this.
| ||||||||||||
1 more comment feedback |
up vote 7 down vote | This may not be an answer what you want, but I had same kind of problem. In my case, when I added a view controller's view to another view controller's view as a subview, the subview was received viewWillAppear only in iOS 5.0 not iOS 4.X. So I added a nasty condition. [self.view addSubview:self.viewController.view]; if ([[[UIDevice currentDevice] systemVersion] compare:@"5.0"] == NSOrderedAscending) { [self.viewController viewWillAppear:animated]; } From iOS 5.0, Apple provides a way to implement custom container view controllers like UINavigationController or UITabController. I think this change affects when viewWillAppear is called. This problem may be solvable if we use -[UIViewController addChildViewController:].
| ||||
|
up vote 4 down vote | The answers above a slightly incomplete.Let's presume you have 2 view controllers, ControllerA, and ControllerB. ControllerA.view is already added to the window(it is the parent), and you want to add ControllerB.view as a subview of ControllerA. If you do not add ControllerB as a child of ControllerA first, the automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers will be ignored, and you will still be called by iOS5, meaning that you'll call your view controller callbacks twice. Example in ControllerA: - (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { return NO; } - (void)viewDidLoad { [super viewDidLoad]; self.controllerB = [[ControllerB alloc] initWithNibName:@"ControllerB" bundle:nil]; [self.view addSubview:self.controllerB.view]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.controllerB viewWillAppear:animated]; } In ControllerB NSLogging in viewWillAppear: - (void)viewWillAppear:(BOOL)animated { NSLog("@ControllerB will appear"); } This will result in iOS5 only displaying that NSLog message twice. i.e. You're automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers has been ignored. In order to fix this, you need to add controllerB as a child of controller a. Back in ControllerA's class: - (void)viewDidLoad { [super viewDidLoad]; self.controllerB = [[ControllerB alloc] initWithNibName:@"ControllerB" bundle:nil]; if ([self respondsToSelector:@selector(addChildViewController:)]) [self addChildViewController:self.controllerB]; [self.view addSubview:self.controllerB.view]; } This will now work as expected in both iOS4 and iOS5 without resorting to the horrible hack of checking iOS version strings, but instead checking on if the function we're after is available. Hope this helps.
| ||
feedback |
up vote 1 down vote | It is iOS5 behavior: viewWillAppear, viewDidAppear, ... are executed automatically after addSubView: for iOS5. So for iOS5 no need to execute manually those methods as need for iOS<5.0. The fix may be: if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { ...execute viewWillAppear or other }
| ||
feedback |
up vote 0 down vote | By this method u know which os u use and put condition if is less then 5.0 or other one [[UIDevice currentDevice] systemVersion] |
相关文章推荐
- 解决:IOS viewDidAppear/viewWillAppear无法被调用
- ios 4.3 中 viewDidAppear没有被调用的解决办法
- addChildViewController后 Childvc viewWillAppear 不调用的问题
- 关于IOS开发中的viewController的viewWillAppear 和viewDidAppear 等调用的总结
- addChildViewController后 Childvc viewWillAppear 不调用的问题
- 关于IOS开发中addSubView上去的viewController的viewWillAppear 和viewDidAppear 等调用的总结
- IOS4多任务下,viewWillAppear不能调用的问题解决 (转)
- ios 4.3 中 viewDidAppear没有被调用的解决办法
- Status bar and navigation bar appear over my view's bounds in iOS 7
- IOS 杂笔-8(loadView、viewDidLoad、viewWillAppear、viewDidAppear等简介)
- iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear的区别及用途
- iOS 5.0 后UIViewController新增:willMoveToParentViewController和didMoveToParentViewCon
- iOS 5.0 后UIViewController新增:willMoveToParentViewController和didMoveToParentViewCon
- viewWillAppear:等无法调用的总结
- ios的视图控制器的viewWillAppear和viewDidAppear什么时候被调用
- viewWillDisappear,viewWillAppear不调用的解决方法
- ios 关于 通过加载 xib 生成的view,调用 addsubviews,sub view的按钮 不相应点击事件的 问题
- iOS 生命周期 -init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear 区别和用途
- iOS: viewWillAppear和viewDidAppear什么时候被调用
- ios view的几种加载函数的区别didFinishLaunchingWithOptions、initWithNibName:bundle、loadView、viewWillAppear