/// Called when the view is about to made visible, before it is added to the hierarchy.
/// Because the view is not yet in the hierarchy at the time this method is called, it
/// is too early in the appearance transition for many usages. Prefer -viewIsAppearing:
/// instead of this method when possible. ...
- (void)viewWillAppear:(BOOL)animated;
/// Called after the view has fully transitioned to visible, when any transition animations have completed.
- (void)viewDidAppear:(BOOL)animated;
/// Called when the view is about to be dismissed, covered, or otherwise hidden.
- (void)viewWillDisappear:(BOOL)animated;
/// Called after the view has fully been dismissed, covered, or otherwise hidden, when any transition animations have completed.
- (void)viewDidDisappear:(BOOL)animated;
// If a custom container controller manually forwards its appearance callbacks, then rather than calling
// viewWillAppear:, viewDidAppear: viewWillDisappear: or viewDidDisappear: on the children these methods
// should be used instead. This will ensure that descendent child controllers appearance methods will be
// invoked. It also enables more complex custom transitions to be implemented since the appearance callbacks are
// now tied to the final matching invocation of endAppearanceTransition.
- (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
- (void)endAppearanceTransition __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
@property(null_resettable, nonatomic,strong) UIView *view; // The getter first invokes [self loadView] if the view hasn't been set yet. Subclasses must call super if they override the setter or getter.
UIViewController.h:117-118:
- (void)loadView; // This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.
- (void)loadViewIfNeeded API_AVAILABLE(ios(9.0)); // Loads the view controller's view if it has not already been set.
UIViewController.h:119:
@property(nullable, nonatomic, readonly, strong) UIView *viewIfLoaded API_AVAILABLE(ios(9.0)); // Returns the view controller's view if loaded, nil if not.
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; // Uses a horizontal slide transition. Has no effect if the view controller is already in the stack.
- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated; // Returns the popped controller.
- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; // Pops view controllers until the one specified is on top. Returns the popped controllers.
- (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated; // Pops until there's only a single view controller left on the stack. Returns the popped controllers.
UINavigationController.h:67-70:
@property(nullable, nonatomic,readonly,strong) UIViewController *topViewController; // The top view controller on the stack.
@property(nullable, nonatomic,readonly,strong) UIViewController *visibleViewController; // Return modal view controller if it exists. Otherwise the top view controller.
@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers; // The current view controller stack.
UINavigationController.h:72:
- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated API_AVAILABLE(ios(3.0)); // If animated is YES, then simulate a push or pop depending on whether the new top view controller was previously in the stack.
// An array of children view controllers. This array does not include any presented view controllers.
@property(nonatomic,readonly) NSArray<__kindof UIViewController *> *childViewControllers API_AVAILABLE(ios(5.0));
...
- (void)addChildViewController:(UIViewController *)childController API_AVAILABLE(ios(5.0));
// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
UIViewController.h:185-186——viewWillDisappear: 注释 "Called when the view is about to be dismissed, covered, or otherwise hidden":被覆盖(covered)本身就是 disappearance 的一种,表明 UIKit 把"被盖住"与"消失"同等对待,而非保留在层级里仅被遮挡。
// ... This method will add the toViewController's view to the superview of
// the fromViewController's view and the fromViewController's view will be removed from its superview after the
// transition completes. ...
// ... it is important to ensure that the toViewController's view is added to the visible view hierarchy
// while the fromViewController's view is removed.
(UIViewController.h:447-449 为 "will add the toViewController's view ... and the fromViewController's view will be removed from its superview after the transition completes",UIViewController.h:454-455 为 "ensure that the toViewController's view is added to the visible view hierarchy while the fromViewController's view is removed"。)UINavigationController 的 push/pop 正是这种容器 transition:转场结束后旧 VC 的 view 被 removeFromSuperview。
反证(VC 仍持有 view):UIViewController.h:119viewIfLoaded "Returns the view controller's view if loaded, nil if not"——view 的"loaded"状态独立于其是否在 window 层级中;第 1 节已证 VC 在栈中被强持有,而 view 属性是 strong(UIViewController.h:116)。
官方文档佐证(URL,本环境不可达,未能在线验证):
Apple《View Controller Programming Guide for iOS》(已归档):
[镜像来源 URL] https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/index.html (该 URL 取自 GitHub 镜像仓库 Yannmm/View-Controller-Programming-Guide-for-iOS-Chinese-Translation 中 Apple 原文链接,镜像内容经 api.github.com 获取)该指南(及 Apple 文档站现行 UINavigationController、UIViewController 页面)对导航栈的描述为:导航控制器在转场时把新栈顶的 view 装入内容区,旧栈顶 view 移出层级、VC 留栈。[推断——指南镜像章节(Overview/Presentations 等)中未逐字出现该句,此段综合 Apple 文档惯常表述与本节头文件注释;请以上方头文件证据为准]
- (void)viewWillUnload API_DEPRECATED("", ios(5.0, 6.0)) API_UNAVAILABLE(tvos) API_UNAVAILABLE(visionos, watchos);
- (void)viewDidUnload API_DEPRECATED("", ios(3.0, 6.0)) API_UNAVAILABLE(tvos) API_UNAVAILABLE(visionos, watchos); // Called after the view controller's view is released and set to nil. For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc.
注释原文即历史行为的自述:"Called after the view controller's view is released and set to nil. For example, a memory warning which causes the view to be purged."
UIViewController.h:207(现行行为的最权威一行注释):
- (void)didReceiveMemoryWarning; // Called when the parent application receives a memory warning. On iOS 6.0 it will no longer clear the view by default.
- (void)didReceiveMemoryWarning; // Called when the parent application receives a memory warning. On iOS 6.0 it will no longer clear the view by default.
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application; // try to clean up as much memory as possible. next step is to terminate app
- (void)applicationWillTerminate:(UIApplication *)application;
注释直白:"try to clean up as much memory as possible. next step is to terminate app"——警告之后就是杀进程(jetsam)。
/// Tells the delegate that the application has become active
/// - Note: This method is not called if `UIScene` lifecycle has been adopted.
- (void)applicationDidBecomeActive:(UIApplication *)application API_DEPRECATED("Use UIScene lifecycle and sceneDidBecomeActive(_:) from UISceneDelegate or the UIApplication.didBecomeActiveNotification instead.", ios(2.0, 26.0), tvos(9.0, 26.0), visionos(1.0, 26.0)) API_UNAVAILABLE(watchos);
UIApplication.h:373:
/// Tells the delegate that the application is now in the background
/// - Note: This method is not called if `UIScene` lifecycle has been adopted.
- (void)applicationDidEnterBackground:(UIApplication *)application API_AVAILABLE(ios(4.0)) API_DEPRECATED("Use UIScene lifecycle and sceneDidEnterBackground(_:) from UISceneDelegate or the UIApplication.didEnterBackgroundNotification instead.", ios(4.0, 26.0), visionos(1.0, 26.0)) API_UNAVAILABLE(watchos);
同组:applicationWillResignActive:(UIApplication.h:369)、applicationWillEnterForeground:(UIApplication.h:377)。全部带 - Note: This method is not called if 'UIScene' lifecycle has been adopted. 与指向 scene 对应方法的弃用信息。
// Conditions that help the system shell determine whether the scene should be destroyed for certain actions
@property (nonatomic, copy) NSSet<UISceneDestructionCondition *> *destructionConditions API_AVAILABLE(ios(26.0), tvos(26.0), visionos(26.0)) API_UNAVAILABLE(watchos) NS_REFINED_FOR_SWIFT;
/// Called when the view is becoming visible at the beginning of the appearance transition,
/// after it has been added to the hierarchy and been laid out by its superview. This method
/// is very similar to -viewWillAppear: and is always called shortly afterwards (so changes
/// made in either callback will be visible to the user at the same time), but unlike
/// -viewWillAppear:, at the time when -viewIsAppearing: is called all of the following are
/// valid for the view controller and its own view:
/// - View controller and view's trait collection
/// - View's superview chain and window
/// - View's geometry (e.g. frame/bounds, safe area insets, layout margins)
/// Choose this method instead of -viewWillAppear: by default, as it is a direct replacement
/// that provides equivalent or superior behavior in nearly all cases.
- (void)viewIsAppearing:(BOOL)animated API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
注意两点:(a) 它解决的是 viewWillAppear: 时机过早("before it is added to the hierarchy",UIViewController.h:162-163)的问题;(b) 本 SDK 将其标注为 API_AVAILABLE(ios(13.0))——该方法于 2023 年(iOS 17 SDK / WWDC23)首次引入,Apple 随后把可用性回溯下调至 iOS 13(back-deployment),当前头文件以 ios(13.0) 标注[推断——ios(13.0) 标注为头文件可证;"iOS 17 SDK 首次引入后回溯"为知识背景,本环境无法在线验证 Apple 文档变更史]。
/// Call to manually request a properties update for this view controller. // 190-191
/// Multiple requests may be coalesced into a single update alongside the next layout pass.
- (void)setNeedsUpdateProperties API_AVAILABLE(ios(26.0), ...) // 192
/// Override point for subclasses to update properties of this view controller or its view. // 193-194
- (void)updateProperties NS_REQUIRES_SUPER API_AVAILABLE(ios(26.0), ...) // 195
- (void)updatePropertiesIfNeeded API_AVAILABLE(ios(26.0), ...) // 198
以及 childViewControllerForInterfaceOrientationLock(UIViewController.h:725)、prefersInterfaceOrientationLocked(740)、setNeedsUpdateOfPrefersInterfaceOrientationLocked(743)——界面方向锁定;UIScene.h:59destructionConditions(scene 销毁条件);UINavigationController.h:89-91interactiveContentPopGestureRecognizer(API_AVAILABLE(ios(26.0)...),全屏内容区 pop 手势)。