当你没有正确地创建你的视图层次时,我已经阅读了很多关于viewWillAppear
遇到问题的人的帖子。我的问题是我无法弄清楚这意味着什么。
如果我创建一个RootViewController
并在该控制器上调用addSubView
,我希望添加的视图可以连接到viewWillAppear
事件。
有没有人有一个复杂的程序化视图层次结构的例子,成功地在每个级别接收viewWillAppear
事件?
Apple的Docs声明:
警告:如果属于视图控制器的视图直接添加到视图层次结构中,则视图控制器将不会收到此消息。如果向视图层次结构插入或添加视图,并且它具有视图控制器,则应直接向关联的视图控制器发送此消息。未能发送视图控制器此消息将阻止显示任何关联的动画。
问题是他们没有描述如何做到这一点。 “直接”是什么意思?你如何“间接”添加一个视图?
我对Cocoa和iPhone相当新,所以如果除了基本的Hello World垃圾之外还有来自Apple的有用示例,那将会很不错。
我将此代码用于推送和弹出视图控制器:
推:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UIViewController *viewController = ...;
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self];
}
流行:
[self.navigationController pushViewController:detaiViewController animated:YES];
[detailNewsViewController viewWillAppear:YES];
..它对我来说很好。
一个非常常见的错误如下。你有一个视图,[[self.navigationController popViewControllerAnimated:YES] viewWillAppear:YES];
,另一个,UIView* a
。您将b添加到a作为子视图。如果你试图在b中调用viewWillAppear,它将永远不会被触发,因为它是a的子视图
谢谢iOS 13。
UIView* b
,ViewWillDisappear
,ViewDidDisappear
和ViewWillAppear
将不会在iOS 13上的呈现视图控制器上调用,该控制器使用不覆盖整个屏幕的新模式演示。
积分将去ViewDidAppear
。他真的救了我的一天。
我认为添加子视图并不一定意味着视图会出现,所以没有自动调用类的方法它会
我认为它们的意思是“直接”是通过与xcode“导航应用程序”模板相同的方式挂钩,它将UINavigationController设置为应用程序UIWindow的唯一子视图。
使用该模板是我能够在UINavigationController中按下/弹出这些控制器时在对象ViewControllers上调用Will / Did / Appear / Disappear方法的唯一方法。这里的答案中没有其他解决方案适用于我,包括在RootController中实现它们并将它们传递给(子)NavigationController。这些函数(将/将/出现/消失)仅在我的RootController中显示/隐藏顶级VC,我的“登录”和navigationVCs,而不是导航控制器中的子VC,因此我没有机会“将它们传递给Nav VC”。
我最终使用UINavigationController的委托功能来查找我的应用程序中需要后续功能的特定转换,这是有效的,但它需要更多的工作才能使消失和显示功能“模拟”。
在今天几个小时之后对这个问题猛烈抨击之后,让它开始工作也是一个原则问题。任何使用自定义RootController和子导航VC的工作代码片段都将非常受欢迎。
如果这有助于任何人。我有一个类似的问题,我的[viewController.view addSubview:anotherViewController.view]
没有射击ViewWillAppear
。经过大量的游戏,我意识到问题是控制我的UITableViewController
的UINavigationController
不在根视图上。一旦我解决了这个问题,它现在就像一个冠军。
我自己就是这个问题,我花了3个小时(其中2个谷歌搜索)来解决它。
结果有帮助的是简单地从设备/模拟器中删除应用程序,清理然后再次运行。
希望有所帮助
UITableView
将委托设置为根视图控制器。
对于斯威夫特。首先创建协议以在viewWillAppear中调用您要调用的内容
[self.navigationController setDelegate:self];
第二,创建类
protocol MyViewWillAppearProtocol{func myViewWillAppear()}
}
第三,使ForceUpdateOnViewAppear的实例成为可以访问导航控制器的相应类的成员,并且只要存在导航控制器就存在。它可以是例如导航控制器的根视图控制器或创建或呈现它的类。然后尽早将ForceUpdateOnViewAppear的实例分配给Navigation Controller委托属性。
在我的情况下问题是自定义过渡动画。当设置class ForceUpdateOnViewAppear: NSObject, UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool){
if let updatedCntllr: MyViewWillAppearProtocol = viewController as? MyViewWillAppearProtocol{
updatedCntllr.myViewWillAppear()
}
}
modalPresentationStyle = .custom
没有调用
在自定义过渡动画类需要调用方法:viewWillAppear
和beginAppearanceTransition
在我的情况下,这只是ios 12.1模拟器上的一个奇怪的错误。在真实设备上启动后消失。
我创建了一个解决这个问题的类。只需将其设置为导航控制器的委托,并在视图控制器中实现简单的一个或两个方法 - 将在视图即将显示或通过NavigationController显示时调用
endAppearanceTransition
ViewWillAppear是UIViewController类的覆盖方法,因此添加一个subView不会调用viewWillAppear,但是当你从viewController呈现,push,pop,show,setFront或popToRootViewController然后viewWillAppear将会调用所呈现的viewController。
您应该只有1个UIViewController随时处于活动状态。您想要操纵的任何子视图应该是 - subVIEWS - 即UIView。
我使用一种简单的技术来管理我的视图层次结构,并且因为我开始以这种方式做事,所以还没有遇到问题。有两个关键点:
“屏幕的价值”是什么意思?它的目的有点模糊,但通常它是你的应用程序的一个功能或部分。如果你有几个屏幕具有相同的背景图像但不同的叠加/弹出窗口等,那应该是1个视图控制器和几个子视图。你永远不应该发现自己使用2个视图控制器。请注意,如果您希望屏幕的某些区域显示在多个视图控制器中,您仍然可以在一个视图控制器中实例化UIView并将其添加为另一个视图控制器的子视图。
至于UINavigationController - 这是你最好的朋友!关闭导航栏并为动画指定NO,您可以根据需要切换屏幕。如果它们位于层次结构中,您可以推送和弹出视图控制器,或者您可以准备一组视图控制器(包括包含单个VC的数组),并使用setViewControllers将其设置为视图堆栈。这使您可以完全自由地改变VC,同时获得在Apple的预期模型中工作的所有优势,并使所有事件等被正确解雇。
这是我每次启动应用程序时所做的事情:
(注意从基于窗口开始只是个人偏好 - 我喜欢自己构建内容,所以我确切地知道它们是如何构建的。它应该可以与基于视图的模板一起工作)
所有事件都正常开火,基本上生活都很好。然后,您可以花费所有时间编写应用程序的重要部分,而不是试图手动破解视图层次结构。