1012 - iOS之View Controllers的理解

2023-05-16

需求现在只是把navigationController的导航栏字体给去掉,不过既然都看了,那就直接刚一下吧。

阅读官网文档的顺序:

                                   Managing Content in Your App's Windows(link)

                                  -->Displaying and Managing Views with a View Controller(link)

                                  -->Showing and Hiding View Controllers(link)

                                  -->Creating a Custom Container View Controller(link)

                                  (先把这四个基本的文档看了,然后再做UINavigationController,  不能更多了,拖项目了)

 

 

首先第一个文档:

Managing Content in Your App's Windows(link)

    --Build your app’s user interface from view controllers, and change the currently visible view controller when you want to display new content.

    这篇文档主要介绍了如何通过view controller来搭建你的用户界面,以及当你想展现新的内容时,如何去更换 当前的 可见的view controller

--Each scene in your app’s UI contains a window object and one or more view objects.

    你的app中的每一个scene都包含了一个window对象多个view视图对象。scene是iOS 13及之后的新特性,具体去看生命周期的相关内容。

--The window serves as an invisible container for the rest of your UI, acts as a top-level container for your views, and routes events to them.

   window对象是一个app中“最最顶级的 不可见的”容器,容纳了你所有的UI视图,而且iOS也是通过window把各种事件路由到各个“你的UI视图”中,例如点击事件,最小化app事件等等。

--The views provide the actual content that users see onscreen, drawing text, images, and other types of custom content.

   而view对象则是提供了“实际的 客户可见的”内容,例如屏幕上的 绘制的文本、图片、其他的 你定义的 视图内容

--Windows are long-lived objects, and you dismiss them only when tearing down your scene's entire UI.

  window是一个长存的对象,只有你拆除了一个scene中的所有UI时,这个window才会被关闭。而view对象则是会频繁地被你在这个window上拆除搭建。

    scene、window、view范围的视图展示:

来源于苹果官网
图片来源于苹果官网

下面是view controller的介绍了:

--A view controller manages a single set of views for your app, and it keeps the information in those views up-to-date.

   一个view controller管理了一群视图,并且view controller需要去保证 与这些视图相关的 信息是最新的。

--Each window has a root view controller, which you use to specify the window's initial set of views.

   每一个window都必须有一个根视图控制器,这个 根视图控制器 你可以用来初始化 你最开始需要的 视图集。

--When you want to change that set of views, you tell UIKit to present or dismiss additional view controllers.

   如果你想改变某个view controller上的视图集,那你可以通过告知UIKit来解除这个view controller或者新增额外的view controller,都可以。

--UIKit handles the transition from one set of views to another, and manages your app's entire interface through your view controller objects.

   UIKit是通过view controller来操纵 一个视图集转换到另外一个视图集的 ,从而是屏幕上的视图发生改变。所以view controller是UI的核心角色。

Define View Controllers for Each Unique Page of Content

--When designing the UI for a new app, first divide that UI into distinct pages of content.

   当你设计一个app的UI时,你首先应该 根据内容的不同 将UI划分成不同的页,这样的思想很重要。

--Only the structure and overall appearance of each page is important;the specific data you display from each page is not.

    view的具体数据并不重要,重要的是每一页的结构和整体外观。

--In fact, many apps use the same type of page in multiple places, filling each copy with different sets of data.

    实际上,很多app的每一页的整体结果和外观布局是差不多的,只是把不同的数据填进去而已

--Defining a view controller always involves subclassing and adding custom behavior. Every view controller needs to do the following:

    定义一个view conttroller通常需要子类化并且添加一些你自定义的行为,所以定义一个view controller都必须有以下步骤:

  • Fill its views with data, and update those views when data changes.  //用数据填充view,并时刻更新数据

  • Report data changes back to your data model objects. //随时向你的model层对象报告数据的变化

  • Adjust the size, position, and visibility of views to match the current environment. //调整当前view的布局

  • Facilitate transitions to other pages of content.  //促进页与页内容之间的转换。

Choose the Navigation Model for Your Content:

--To make navigating between those view controllers easy, UIKit provides container view controllers that implement common navigation models.

   为了使各个视图控制器之间的导航更加便捷,UIKit提供了 视图控制器容器 container view controller ,这个容器实现了各个view controller之间的通用的导航模型。

--A container view controller is a special type of view controller that manages other view controllers, which are known as its child view controllers.

  一个 视图控制器容器 的目的就是管理其他 视图控制器 ,在其中的其他视图控制器就叫做该容器的 子视图控制器

--The container's job is to position the root view of each child view controller within the bounds of its own view.

  ”视图控制器容器“ 的工作就是把“子视图控制器”的根视图 放在容器“自身视图”的范围之内。

--Always use the UIKit container view controllers to implement the common navigation models:

   UIKit提供了下面这几种 视图控制器容器 给你使用,一般来讲够用了。

  • UINavigationController(link) manages a stack of child view controllers in a navigation interface. Pushing a new view controller onto the stack replaces the previous view controller. Popping a view controller reveals the view controller underneath.

        UINavigationController是通过栈的形式来管理它的子视图控制器的,所以子视图控制器安的导航就是出栈入栈咯

  • UISplitViewController(link) manages two child view controllers side-by-side (when space is available) in a split-view interface. (When space is constrained, the system displays those view controllers in a navigation interface.) This type of interface is also known as a master-detail interface.

       UISplitViewController是并排分屏管理两个子视图的,前提是屏幕空间足够。空间不够的时候,就变成导航视图来管理

  • UITabBarController(link) displays a row of buttons along the bottom of a tab-bar interface. Selecting a button displays the child view controller associated with that button.

        UITabBarController是在视图的底部放置一栏标签栏,标签栏由一排button组成,点击不同的button就展示响应的子视图控制器的视图,这个标签栏也 称作 选项卡栏。

  • UIPageViewController manages an ordered sequence of child view controllers, presenting only one or two at a time, in a paged interface. The user navigates between those view controllers by swiping or tapping.

       UIPageViewController管理了一队列的子视图控制器,也是分屏展示,一个视图只展示一个或者两个子视图控制器的视图,客户可以通过 滑动或者点击 来实现 子视图控制器 之间的导航。

看一下直观图,图片来源苹果官网:

An illustration of the standard UIKit container interface types, including split-view controller, navigation controller, tab-bar controller, and page-view controller.
图片来源苹果官网

--You can combine multiple UIKit container view controllers to create new navigation models.

   你可以组合几个UIKit提供的 视图控制器容器 来实现不同的导航模型。

--You can also create new container view controllers of your own, allowing you to create entirely new navigation models that are unique to your app.

   你也可以自定义视图控制器容器

--In addition to container view controllers, you can replace the contents of the current view controller with a new view controller at any time.

   除了使用视图控制器容器之外,你也可以直接用 新的视图控制器 来替换当前的视图控制器的内容。不是很懂,单纯是内容?

--Typically, you present new view controllers only as a temporary interruption to the current flow or when your app's UI is very simple.

   通常的,用新的视图控制器去替换当前视图控制器的内容只是当前工作流的一个中断,因而不建议使用。还是乖乖用视图控制器容器吧。但是怎么组合使用视图控制器容器啊?还不是很清晰。肯定有一些是不能直接组合的。

--For information about how to create your own container view controllers, see Creating a Custom Container View Controller.

   关于如何创建一个自定义的视图控制器,参考超链接

Assign a Root View Controller to Each Window

--The root view controller defines the initial navigation model of your window.

  根视图控制器 定义了你的window上最原始的导航模型。

--If you create your windows programmatically, assign a value to the rootViewController property of the window before showing the window.

   人工编程的话,你给window的rootViewController属性赋值,就是定义了该window的根视图控制器了

--Most container view controllers provide minimal UI of their own; the children provide the rest of the content.

   在设计上,你的 视图控制器容器 应该使用尽可能少的UI,而丰富的UI一般事由容器的儿子们提供。

 一个典型的 根视图控制器 结构:

An illustration of the view controllers involved in a typical split view controller interface.
图片来源苹果官网

 

你看,这里的UINavigationController就可以和UISplitViewController组合使用

 

 

接着,看第二个文档:

Displaying and Managing Views with a View Controller(link)

    --Build a view controller in storyboards, configure it with custom views, and fill those views with your app’s data.

    这篇文档说的的是:使用view controller来管理你的视图,并为你的视图填充数据;还有就是通过storyboard创建一个view controller。

--Specifically, a view controller manages a view hierarchy and the state information needed to keep those views up-to-date.

    具体来说,view controller就是管理 视图之间的层次结构 和 视图的状态信息 。这些状态信息是用于告知视图时刻处于最新状态的。

--Most custom view controllers you create are content view controllers—that is, the view controller owns all of its views and manages interactions with those views.

   一般来讲,你玩iOS创建最多的 视图控制器 大多都是用来管理自己的“内容视图”的,并且用来管理这些‘内容视图“中的交互。

--Use content view controllers to present your app’s custom content onscreen, and use your view controller object to manage the transfer of data to and from your custom views.

   使用 内容视图控制器 来管理展示在屏幕上的内容,并使用这个 内容视图控制器对象 来管理 视图 与 数据 之间的传递。内容视图控制器只是根据用途 起的一个称呼罢了。

   看图:

An illustration of the relationship between a view controller, its views, and the data objects from your app.
图片来源苹果官网


--As opposed to a content view controller, a container view controller incorporates content from other view controllers into its view hierarchy.

  恰恰与内容视图控制器相反,视图控制器容器 是将其他的视图控制器的内容视图 合并到自己的视图层次结构中,把视图控制器收纳其中,也就相当于把它的内容也是收入囊中了。

--For information about how to implement a container view controller, see Implementing a Custom Container View Controller(link).

   关于如何实现一个视图控制器容器,参考超链接。

--To define a content view controller, start by subclassing UIViewController.

  定义一个 内容视图控制器 都是从继承UIViewController开始的。

Add Views to Your View Controller

--UIViewController contains a content view, accessible from the view property, which serves as the root view of its view hierarchy.

   UIViewController没意外都是你的ViewController的父类,它提供了一个叫做view的属性,这个属性就是它的内容视图,也是这个controller的视图层次结构中的根视图。注意一下根视图的覆盖范围。

An image of a view controller interface that contains an image view and button.
图片来源苹果官网

 --After adding views to a view controller, always add Auto Layout constraints to set the size and position of those views.

    添加自定义的视图到controller的根视图上之后,记得添加自动布局约束来设置 自定义视图的大小和位置,哎,自动布局还没看。

--Constraints are rules that specify how to size and position each view relative to its parent or sibling view, and they ensure that your views automatically adapt to different environments and devices. For more information, see View Layout(link).

    约束是指 ”如何相对于父视图或同级视图调整每个视图的大小和位置的 “规则,这样确保了内容视图能自动适应不同的环境和设备。有关详细信息,请参见超链接。又越挖越多了。★之后再看,现在没时间

 

Store References to Important Views

--In your storyboard, connect each outlet to the corresponding view, as described in Add an outlet connection to send a message to a UI object(link).

  你可以使用oulet(输出口)关键字来链接你定义的view controller代码和storyboard上面的画图,这样你就可以把它们关联起来了,也就是说你保存了它们的引用,然后就可以去修改这些视图的内容了,具体看超链接

--When you instantiate a view controller, UIKit reconnects any outlets that you configured in your storyboard. UIKit reestablishes these connections before calling your view controller’s viewDidLoad() method, so you can access the objects in those properties from that method.

   ★当你实例化一个view controller的时候,UIKit会重新连接你在storyboard上定义的输出口(outlet),而且在你调用controller的ViewDidLoad()方法之前,UIKit会先重新建立这些输出口的连接,所以你可以直接在ViewDidLoad()方法里面操作这些输出口属性,输出口本身就是一个属性。

--If you create any views programmatically, you must explicitly assign those views to the appropriate properties of your view controller

  如果你是直接编程方式创建view,那么你必须显式的把这些view分配给controller相应的属性,你可以为类增加属性啊。

 

Handle Events Occurring in Views and Controls

--Controls use the target-action design pattern to report user interactions, and some views post notifications or call delegate methods in response to changes.

    控件使用 目标-行为 的设计模式来报告用户的交互行为的,一些视图是通过 发布通知 或者 调用代理方法 的方式来响应控件的更改的。

--A view controller needs to know about many of these interactions so it can update its views, and you have several ways to make that happen:

    一个视图控制器可以通过下面的几种方式来获知用户的多种交互行为,从而对视图进行更改:

  • Implement delegate and action methods in your view controller. This option is simple and easy to implement, but it offers less flexiblity and makes it harder to test and validate your code.

        直接在view controller里面实现 ”代理的方法“ 和 “动作的方法”,这种方式简单,但是不灵活,很难测试和验证你的代码的准确性。

  • Implement delegate and action methods in a class extension on your view controller. This option separates your event-handling code from the rest of your view controller, making it easier to test and validate that code.

        在你的 view controller 的 extension 中实现 “代理的方法”和 “动作的方法”,这种方式把你的 响应交互的方法 从view controller这个大类中分离出来,就是不用都写在一个文件里,这样对你而言,就相对好看一些,容易管理一些,也比较容易测试你的代码。

  • Implement delegate and action methods in dedicated objects that then forward relevant information to your view controller. This option offers the most flexibility and reusability. The separation of responsibilities also makes it easier to write unit tests.

       专门写一个对象来实现 “代理的方法” 和 “动作的方法” ,然后把相关的信息传递给你的view controller,这种方式就更加灵活,也更加方便重用代码,这种分离的思想也极为方便些测试单元。

--To respond to user interactions with controls, define an action method with one of the signatures shown in the following code listing.

    如果你用的是stroryboard编程,然后你的控件要响应用户的交互的话,那么你就要在响应的 动作方法声明 定义前加上@IBAction签名,这样IB才能绑定到相应的方法中。控件是通过方法的参数传递进去方法代码里面的。不要管,反正iOS会帮你传就是了。

Prepare Your Views to Appear Onscreen

--UIKit gives you several opportunities to configure your view controller and views before displaying them onscreen.

    在你的视图展示在屏幕之前,UIKit提供了几个时机给你来陪你的视图。

--When you instantiate your view controller from a storyboard, UIKit creates that object using its init(coder:) method.

    storyboard是通过调用view controller的init(coder:)方法来实例话view controller对象的。

--If your view controller requires custom initialization beyond what a coder object can provide, you can instantiate it programmatically using the instantiateInitialViewController(creator:) method of UIStoryboard.

   如果你的 自定义的初始化代码 超出了编译器能够提供初始化能力,那么你可手动编程地,使用UIStoryBoard提供的instantiateInitialViewController(creator:)方法来初始化你的对象。

--When you present a view controller onscreen, UIKit must first load and configure the corresponding views, which it does using the following sequence of steps:

     在把你的view controller展示在屏幕上之前, UIKit首先会加载并且配置你的视图,UIKit会按照以下步骤来加载配置:

    1、It creates each view using the view’s init(coder:) method.

        通过init(coder:) 方法来创建view controller 中的每一个view

    2、It connects views to the corresponding actions and outlets in the view controller.

        通过outlet把 视图 与 “动作方法”连接起来

    3、It calls the awakeFromNib() method of each view and the view controller.

         调用view controller的和每一个view的awakeFromNib()方法,从nib文件中获取配置数据。nib文件要看storyboard相关内容

    4、It assigns the view hierarchy to view controller’s view property.

        把view的层次结构分配给view controller的view属性。

    5、It calls the view controller’s viewDidLoad() method.

        最后才调用viewDidLoad() 方法加载view

--At load time, perform only the one-time configuration steps you need to prepare the view controller for use.

   在加载时,上面的五步只执行一次,也就是只加载一次view controller而已。所以你可以充分利用加载的这段时间来配置那些额外的视图,额外是指不是这个storyboard上画的视图。也就是不是通过storyboard加进view controller的那些视图。

--UIKit notifies the owning view controller when its views are about to appear onscreen, and updates the layout of those views to fit the current environment, by calling the following methods in order:

    当视图集出现在屏幕上之前,UIKit会通知视图集的拥有者——即视图集的view controller,并先按顺序调用view controller的以下方法:

    1、It updates the view controller's trait collection based on the target window.

        UIkit基于window来更新view controller的特征集合

    2、It calls the viewWillAppear(_:) method to let you know the view controller’s view is about to appear onscreen.

        UIKit调用viewWillAppear(_:) 方法来让你知道view即将展示,所以你可以在这个方法里面写代码

    3、If needed, it updates the current layout margins and calls the viewLayoutMarginsDidChange() method.

        如果有必要,UIKit会调用viewLayoutMarginsDidChange()方法来更新当前的布局边距,边距不是间距

    4、If needed, it updates the safe area insets and calls the viewSafeAreaInsetsDidChange() method.

         如果必要的话,UIKit会更新安全区域的内边距并且调用 viewSafeAreaInsetsDidChange()方法

    5、It calls the viewWillLayoutSubviews() method.

         UIKit第五步会调用viewWillLayoutSubviews() 方法

    6、It updates the layout of the view hierarchy.

        UIKit更新view controller的视图层次

    7、It calls the viewDidLayoutSubviews() method.

        UIKit调用viewDidLayoutSubviews()方法

    8、It displays the views onscreen.

         此时UIKit才会把视图集展示在屏幕上

    9、It calls the view controller’s viewDidAppear(_:) method.

        展示之后,UIKit会调用view controller的viewDidAppear(_:) 方法

--Update the content of your views in the viewWillAppear(_:) method of your view controller.

    建议在view controller的viewWillAppear(_:)方法中更新的视图内容

--Changing the content of many views triggers an automatic layout update, so making changes in that method avoids an additional layout step

    改变多个(子)视图的内容会触发自动布局的更新,所以在viewWillAppear(_:)方法中更新视图内容避免额外的自动布局步骤,提高了性能。

--When making changes, you may use the view controller's traitCollection property to access information about the current environment, such as the display scale or the vertical and horizontal size classes.

    在对视图内容进行修改你,你可能需要用到view controller的tiaitCollection属性,借此属性,你可以访问到当前环境信息,例如视图的显示比例,垂直和水平的大小的类等信息。特征集合tiaitCollection

--Although you can access traits earlier than viewWillAppear(_:), traits aren't guaranteed to be final until that method.

    虽然你可以在viewWillAppear(_:)方法来访问view controller 的特征集合,但是这些特征集合有可能剩下的几个加载步骤中发生改变。

--In iOS 12 and earlier, UIKit only provides a partial set of traits at load time, and doesn't provide a complete set of traits until the viewWillAppear(_:) method. For more information about the available traits, see UITraitCollection(link).

     在iOS 12版本及其以前,UIKit只提供view controller的特征集合中的部分特征,并且只有在调用viewWillAppear(_:)方法之后才提供所有的特征。更多关于view controller的特征集合信息,参考超链接。

 

 

接下来第三个文档:

Showing and Hiding View Controllers(link)

--Display view controllers using different techniques, and pass data between them during transitions.

这篇文章介绍了用多种技术来展示view controller的视图,还介绍了怎么在 变换view controller的时候 传递数据。

 

--Every window has a root view controller, which provides the initial content for your window. Presenting a new view controller changes that content by installing a new set of views in the window.

    每一个窗口都有一个根视图控制器,而这个根视图控制器提供了最初始的视图内容给这个窗口。你是通过在window上新建一个view controller 来改变屏幕视图的,因为新的controller有自己的视图集,取代了旧controller的位置。

--When you no longer need the view controller, dismissing it removes its views from the window. You present view controllers in one of two ways:

    当你不再需要一个视图控制器时,你关闭它的话,它的视图集将会从window上移除。你可以通过以下两种方式之一呈现你的视图控制器。确切来讲时呈现视图控制器里的视图集,以后就直接说呈现视图控制器好了,官网少打字我也懒得多打字。

  • Configure presentations visually in your storyboard

        在storyboard上直观的配置你的演示稿(即是视图集)

  • Embed them in a container view controller.

        把这些view controller嵌入的视图控制器容器中。

  • Call methods of UIViewController directly.

       直接调用UIViewController里面的方法。

    上面的两种方式都提供了 不同程度的控制权 来控制 view controller 的展示,和view controller的关闭。我也不知道为啥是两种,可能第一步是可选的吧,因为配置视图,你可以storyboard也可以用编程实现。


Specify Presentations Visually in Your Storyboard File

--A segue is a visual representation of a transition from one view controller to another.

   storyboard的“切入”是一种在两个view controller间的可视化的切换

--When that action occurs, UIKit creates the view controller at the other end of the segue and presents it automatically.

   ”切入“segue表征着一个动作,当该动作发生时,UIKit就会在“切入”箭头的末端自动地新建一个view controller并呈现它。

直接看图吧:

An illustration of a segue between two view controllers. Tapping a table row in the first view controller triggers the segue.
图片来源苹果官网

--Start a segue from any object that implements an action method, such as a control or gesture recognizer

    使用segue的对象,该对象内部需要实现了相关的“动作方法”,例如控件和手势识别。

--The storyboard shows segues as an arrow between two view controllers.

   在storyboard中,“切入”用一个箭头来表示两个view controller间的关系

--You use this information at runtime to customize the segue further, as described in Customizing the Behavior of Segue-Based Presentations(link).

   你在storyboard选择segue的时候,会有segue的相关信息配置,你可以使用seguw这些信息来修改你的view controller之间的切换行为,或者其他行为,也可以在运行期间修改这些信息来修改自定义你的segue行为。如何定义segue的行为,参考超链接

--For information about how to dismiss a view controller in your storyboards, see Dismissing a View Controller with an Unwind Segue(link).

    更多关于如何在storyboard关闭你的view controller 的信息,参考超链接。

 

Let the Current Context Define the Presentation Technique

   让“当前上下文”定义“视图展示”的技术

--Reusing the same view controller in multiple places creates a potential problem: presenting it in different ways based on the current context.

   在多个地方重用同一个view controller潜在这样的一个现象:展示view controller的时候,可能要基于当前的 上下文环境 来以不同的方式呈现view controller。

--For example, you might want to embed it in a navigation controller in one instance, but present it modally in another.

   例如你可能想在当前 上下文 中把view controller嵌入到container中,你也可能想把这个view controller以模态的方式呈现出来。我主要是为了了解一下模态是什么。

    「模型」这个词有「事物的特定抽象模式」的含义,而「状态」一词,可以表示「事物在某种情形下的表现」。这两者结合一下,「模态」这个词便呼之欲出了。它指的是模式的某种特定的状态。模态框是处于一种特定状态下的窗体,它会把我们从正常状态中中断出来,将关注点放在这个特定状态的处理上。例如删除文件,系统就会弹出一个窗体,强制要求你确认或者取消,这个窗体就叫做模态窗体。当模态框出现的时候,它会屏蔽掉所有其他操作,用户可关注的范围只限于当前的模态框内部,除非你特意去关闭这个模态框,结束这种中断,回到原先正常的流程中去。当然模态框这种设计理念,暗含着一种强制性的思路。所以模态就是某种模型下的某种特定状态,例如 在北京的广东人 ,广东人是模型,在北京是状态。广东人已经对张三这个具体的人抽象了一层了。

    模态解释的参考链接:https://segmentfault.com/q/1010000004315227/a-1020000004641573

 

--UIKit solves this problem with the show(_:sender:) and showDetailViewController(_:sender:) methods of UIViewController, which present the view controller in the most appropriate way for the current context.

   为了解决在 当前上下文 中以最恰当的方式呈现view controller ,UIKit提供了show(_:sender:)showDetailViewController(_:sender:) 两个方法给你使用。

--When you call the show(_:sender:) or showDetailViewController(_:sender:) method, UIKit determines the most appropriate context for the presentation.Specifically, it calls the targetViewController(forAction:sender:) method to search for a parent view controller that implements the corresponding show method.

    当你调用show(_:sender:)方法时,UIKit是通过调用targetViewController(forAction:sender:)方法来从继承层次中向上(父类)查找实现了show(_:sender:) 的view controller 的并执行该show(_:sender:)方法的,然后呈现。

--A UINavigationController object's implementation of the show(_:sender:) method pushes the new view controller onto its navigation stack.

   例如,一个UINavigationController对象实现的show方法就是把一个新的view controller推进导航栈中。

 

Embed a View Controller Inside a Container View Controller

--Embedding a child view controller presents it using a container-specific approach. For example, a navigation controller initially positions the child view controller offscreen and then animates it into position onscreen.

  vc container是用特定的方式来表示 嵌入子视图控制器 这个过程的。例如,导航控制器最初是把 子视图控制器 放置在屏幕外的,然后再动画式的把 VC 移到屏幕中。

--The standard UIKit container view controllers work with segues and the show(_:sender:) and showDetailViewController(_:sender:) methods to embed view controllers as children.

   在stroryboard的segues方式中,UIKit是通过调用show方法来嵌入移除子 VC 的。纯编程嵌入移除子VC的话,也有相应的API提供。

--Use the methods in the following table to perform one-time configuration of your view controller, for example when restoring your app's UI to a previous state.

    一次性配置VC的方法,例如将VC的 UI 恢复到前一状态下的UI。就介绍了四个 container VC的总共四个方法,看原文。

 

Present a View Controller Modally

模态显示VC

--Use modal presentations to create temporary interruptions in your app's workflow, such as prompting the user for important information.

    模态是指 打断当前的app工作流 来显式视图,例如提示客户输入重要信息时。

--A modal presentation covers the current view controller wholly or partially, depending on the presentation style you use.

   模态的显示 是覆盖 整个屏幕还是部分屏幕 取决于当前环境的显示 的风格。确切来讲就是trait environment。To configure a --modal presentation, create the new view controller and call the present(_:animated:completion:) method.

    你可以通过调用 VC 的present方法来进行模态显示。

--To change the styles, modify the modalPresentationStyle and modalTransitionStyle properties of the view controller you present.

   你可以通过修改 VC 的 modalPresentationStylemodalTransitionStyle 属性来修改模态显示的风格。

--To dismiss a modally presented view controller, call the view controller's dismiss(animated:completion:) method.

   移除 VC 的模态显示,你可以调用dismiss方法。

 

终于,第四个文档了。

Creating a Custom Container View Controller (link)

--Create a composite interface by combining content from one or more view controllers with other custom views.

container的作用就是,通过将来自 “一个或多个视图控制器的内容”与“其他自定义视图“ 进行组合 来创建复合界面。

 

--Container view controllers promote better encapsulation by separating out your content from how you display that content onscreen.

  container 将“你的视图内容”与你展示内容的“方式”分离,从而提供了更好的封装性。

--Unlike a content view controller that displays your app’s data, a container view controller displays other view controllers, arranging them onscreen and handling navigation between them.

   container VC 的主要目的不在于展示 VC ,而在于如何在各个子VC之间导航,还有如何协调各个子VC。当不要忘记container VC自身也是一个VC,它也可以有自己的视图内容的。

--Each child continues to manage its own view hierarchy, but the container manages the position and size of that child’s root view.

   container VC 会合并“子VC的视图内容”到自己的视图层次中,管理子VC的根视图的大小和位置。但是子VC仍然自己管理自己的视图层次。

 看图:

图片来源苹果官网

 

 Add a Child View Controller Programmatically to Your Content

以编程的方式添加一个子VC到你的视图内容中。

--For each new child view controller you add to your interface, perform the following steps in order:

    动态地增删你的子VC,你需要执行以下几个步骤:

    1、Call the addChild(_:) method of your container view controller to configure the containment relationship.

         在你的 container VC中调用addChild方法 来确定容纳关系

    2、Add the child’s root view to your container’s view hierarchy.

         把子VC的根视图添加到container的视图层次中

    3、Add constraints to set the size and position of the child’s root view.

        设置子VC根视图的布局约束

    4、Call the didMove(toParent:) method of the child view controller to notify it that the transition is complete.

         调用子VC中的didMove方法来通知container,子VC之间的切换已经完成。

--The following example code instantiates a new child view controller from a storyboard and embeds it as a child of the current view controller.

   下面的代码展示了,以storyboard方式,在一个container中如何初始化一个子VC,并潜入container中。

// Create a child view controller and add it to the current view controller.
let storyboard = UIStoryboard(name : "Main", bundle : .main) ;
if let viewController = storyboard.instantiateViewController(identifier : “imageViewController") as? ImageViewController {
   // Add the view controller to the container.
   addChild(viewController)
   view.addSubview(viewController.view)
            
   // Create and activate the constraints for the child’s view.
   onscreenConstraints = configureConstraintsForContainedView(containedView  : viewController.view, stage : .onscreen)
   NSLayoutConstraint.activate(onscreenConstraints)
     
   // Notify the child view controller that the move is complete.       
   viewController.didMove(toParent: self)
}

 -- UIKit normally routes information to each of your app’s view controllers independently.When a container-child relationship exists, UIKit routes many requests through the container view controller first, giving it a chance to alter the behavior for any child view controllers.

   一般来讲UIKit会独立的分发消息到各个VC。但如果是一个container VC的话,UIKit会把消息发给container VC,让container VC来管理对子VC的消息的分发,而不再是独立的分发给子VC了。所以,container VC有强制子VC的外观和行为的能力。

 

Remove a Child View Controller from Your Content

--To remove a child view controller from your container, perform the following steps in order:

    从你的container VC中移除子VC有以下几个步骤:

    1、Call the child’s willMove(toParent:) method with the value nil.

         第一步、用nil值去调用子VC的willMove方法,就是nil作参数。

    2、Deactivate or remove any constraints for the child’s root view.

         第二步、 停用或者移除子VC的根视图

    3、Call removeFromSuperview() on the child’s root view to remove it from the view hierarchy.

          第三步、在子视图的 根VC 中调用removeFromSuperview方法,这样就可以从contianer VC的视图层次移除自身视图了。

    4、Call the child’s removeFromParent() method to finalize the end of the container-child relationship.

          第四步、调用子VC的removeFromParent方法来完成容纳关系的终极,没有第五步了。

--Breaking a container-child relationship tells UIKit that your container view controller is no longer displaying the child’s content. You can still maintain other references to the child view controller. For example, UINavigationController manages a stack of child view controllers, but it maintains a container-child relationship with only one or two of those children at any given time.

    断开容纳关系,意味着,你的 container VC 不再展示子VC的内容了。但是只用你其他地方还持有这个子VC的引用,你仍然是可以直接使用这个子VC的。例如,navigationController在任意一个时刻都只是和一个或者两个子VC保持着 容纳关系 而已,也就是说栈中的其他子VC在这个时刻并不与NavigationController保持着容纳关系,轮到它时才有这种容纳关系。

 

 Embed a Child View Controller in Your Storyboard UI

 在storyboard中嵌入子VC

额,直接看图吧:

图片来源苹果官网

 

--A container view is a proxy view that stands in for the content of a child view controller. When you add one to your interface, it looks like a normal view, but it has an attached view controller.

   一个container视图只是子VC的代理视图,当你添加container视图在storyboard上时,实际上它链接着一个container VC的。

 --However, don’t add any subviews to the container view itself. Instead, add them to the view of the attached view controller.

   不要直接添加子view 在container 的view中,而是将 子VC 添加到 container VC中,以展示 子VC 的方式展示 子view。虽然方法的名字叫做addSubview。

--After creating the new view controllers, UIKit adds them as children of the original view controller you requested. You don’t need to call addChild(_:) yourself.

   当你在storyboard中的container VC添加子VC的时候,UIKit会自动地设置父子关系,不需要你显示地调用addChild方法。

 

Support Additional Container Behaviors

--Consider implementing the following additional behaviors in your custom container view controllers:

    考虑在你的container VC中实现以下方法,以便实现更多的行为。一般都是很有用的的方法,不然文档不会提及。

  • Override show(_:sender:), and use it to present a new child view controller.

        重写show方法,并使用这个方法来呈现你的子VC

  • Override showDetailViewController(_:sender:), as needed, to present a secondary child view controller.

        重写showDetailViewController方法,可以呈现第二个子VC

  • Update additionalSafeAreaInsets to account for decoration views that might obscure the content of your children.

        修改additionalSafeAreaInsets属性的值,这样可以设计模拟你的子视图的装饰视图。

  • Call setOverrideTraitCollection(_:forChild:) to change the traits of your child view controllers. For example, you might designate a child view controller as always horizontally or vertically compact.

        调用VC的setOverrideTraitCollection方法来改变你的VC的特征集合,例如你可以指派一个子VC的视图一直保持垂直紧凑或者水平紧凑。

  • Override childForScreenEdgesDeferringSystemGestures or childForHomeIndicatorAutoHidden to let a child view controller determine the behavior for system gestures.

        修改VC的childForScreenEdgesDeferringSystemGestures or childForHomeIndicatorAutoHidden计算属性,这样可以让子VC来决定响应系统手势的行为。

  • Override allowedChildrenForUnwinding(from:) to limit the set of child view controllers that are targets of an unwind segue action.

        重写allowedChildrenForUnwinding(from:)方法,来限制unwind segue的 目标子VC集 的大小和行为。

For more information, see the descriptions in UIViewController(link).

更多详情,参考超链接。即是UIViewController的API文档。

 

 

 

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1012 - iOS之View Controllers的理解 的相关文章

  • 如何处理 iPhone 屏幕尺寸/背景图像分辨率

    在 iPhoneX 之后 我真的很纠结于支持所有设备的图像尺寸和命名约定 有没有办法在 4 7 5 5 和 5 8 屏幕上使用 3x 图像 全屏图像视图应该使用的确切尺寸是多少 您可以使用图像 pdf格式 因此您只需要管理 1x 的单比例图
  • 如何处理 iPhone 6S Plus 字体大小?

    与其他屏幕尺寸相比 iPhone 6S Plus 的屏幕非常大 我似乎无法找到一种在不以编程方式调整大小的情况下处理标签字体大小的好方法 如何调整标签的字体大小 使其在 iPhone 5 上看起来更小 在 iPhone 6 Plus 上看起
  • 如何将 Android 应用程序添加到已在 iOS 应用程序中使用的现有 Firebase 项目?

    我一直在我的 iOS 应用程序中使用 Firebase 项目 我现在想开始为 Android 应用程序使用相同的 Firebase 项目及其所有数据库和存储 在您的应用程序下Overview菜单 你应该按添加另一个应用程序并选择Androi
  • iOS后台获取时间限制崩溃

    我已经设置了背景获取 使用大纲NSScreencast 第 92 集 http nsscreencast com episodes 92 background fetch BOOL application UIApplication app
  • 如何将 NSMutableArray 添加到 NSMutableArray Objective-c

    我正在从 Java 切换到 Objective c 但遇到了一些困难 我已经搜索过这个问题但没有取得太大成功 我有一个存储 NSMutableArrays 的 NSMutableArray 如何向数组添加数组 您可以在数组中存储对另一个数组
  • 与 parse-server 和 auth0 的自定义身份验证集成

    我想将 auth0 com 与开源解析服务器结合使用 我当前的方法是通过 iOS 的 Lock 库使用标准登录从 auth0 获取令牌 使用该令牌 我想在解析服务器上调用自定义身份验证方法 该方法检查令牌是否有效 如果有效则将登录用户 我的
  • iOS 上关键 ClientState 警告的默认访问速度缓慢

    在测试我的 iOS 应用程序时 我收到 对关键 ClientState 的默认访问速度慢 耗时 0 034635 秒 容差为 0 020000 警告 它似乎是间歇性发生的 我试图环顾四周看看它是关于什么的 但我并不完全确定 任何帮助表示赞赏
  • 在 Xcode 中查找未使用的文件

    我最近开始开发一个新应用程序 它基本上是我以前制作的应用程序的副本 但做了一些更改 为了制作这个新应用程序 我复制了旧应用程序并删除了一些不需要的内容 我想知道 有没有办法知道 Xcode 中正在使用哪些类文件 或者有什么关于如何查找未使用
  • Apple 由于崩溃而拒绝了我的应用程序,无法重现它

    我刚刚上传了一个应用程序到应用程序商店 它是为ios 7开发的 他们拒绝了该应用程序 因为我无法重现崩溃 他们向我发送了这份崩溃报告 Exception Type EXC BAD ACCESS SIGSEGV Exception Subty
  • 无法在 xcode 8 beta 6 上编译 AWS CustomIdentityProvider

    我在 iOS 应用程序中使用 Amazon Cognito 和 Facebook 登录 直到 beta 5 为止此代码从这个SO线程 https stackoverflow com questions 37597388 aws cognit
  • Bootstrap 响应式表格在 iOS 设备上无法垂直滚动

    这就是我所拥有的 div class table responsive table class table style background transparent table div 我正在使用以下 bootstrap css 文件 ht
  • 广告标识符和标识符ForVendor返回“00000000-0000-0000-0000-000000000000”

    我已经实现了这个方法来获得advertisingIdentifier and identifierForVendor NSString advertisingIdentifier if NSClassFromString ASIdentif
  • iOS绘图3D图形库[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在搜索一个可以帮助我绘制 3D 图表的库 我想要类似的东西这一页 http www math uri edu bkaskosz fla
  • UITableViewCell 内嵌套 UIStackView 内的 UILabel 有时会被截断

    我的一个表设置中有一个表视图单元格 其中包含以下视图层次结构 外部水平 stackview 固定到单元格内容视图的尾部 前部 底部和顶部边缘 右侧标签固定到其父 stackViewHackView 的尾部 前部 底部和顶部边缘 在我的控制器
  • 使用未声明的类型“对象”

    这太奇怪了 通常我可以理解未声明的类 但这是声称 Object 类本身未声明 NSObject 可以工作 但我的项目设置方式我需要它是一个纯 Swift 对象 我的类标题如下所示 import UIKit import Foundation
  • 隐藏 UITableview 单元格

    我正在尝试从 UITableView 中隐藏单元格 就像删除操作一样 但我只想隐藏它以便稍后在相同位置显示它 我知道 UITableViewCell 有一个名为 隐藏 的属性 但是当我使用此属性隐藏单元格时 它会隐藏但没有动画 并且会留下空
  • 如何制作像 Facebook 应用程序一样的登录屏幕?

    如何制作像 Facebook 应用程序一样带有 电子邮件 和 密码 文本字段的登录屏幕 Facebook登入 http extdesenv com wp content uploads 2012 05 facebook login ios
  • 如何安全地重命名 iOS 分发配置文件?

    我几个小时前刚刚提交了我的第一个应用程序 现在处于 等待审核 状态 但我犯了一个错误 我已经命名了我的分配配置文件My Company Distribution Profile 我应该做的事情被命名为我的发行版配置文件My GAME Dis
  • 带有自定义字体的 UILabel 错误呈现

    在我的 iPhone 应用程序中 我为所有 UILabel 设置了自定义字体 更准确地说 我对 UILabel 进行了子类化 重写了一个方法 在该方法中设置了自定义字体 然后将 IB 中的所有标签设置为该自定义类 现在的问题是 所有文本都渲
  • TestFlight 安装的应用程序因 Swift 包管理器依赖项而崩溃

    我们已经迁移了一些 CocoaPod 依赖项 以便在 Xcode 11 中使用 Swift Package Manager 进行构建和链接 但是 每当我们将应用程序提交到 AppStore Connect 并使用 TestFlight 进行

随机推荐

  • Adblock Plus Rules 自用 2021

    Adblock Plus Rules obsolete ZhihuCSDNBilibiliBaidu 64 64 static zhihu com heifetz lib js 64 64 static zhihu com heifetz
  • pandas函数 apply、iterrows、iteritems、groupyby

    apply DataFrame span class token punctuation span span class token builtin apply span span class token punctuation span
  • PyTorch中 tensor.detach() 和 tensor.data 的区别

    以 a data a detach 为例 xff1a 两种方法均会返回和a相同的tensor xff0c 且与原tensor a 共享数据 xff0c 一方改变 xff0c 则另一方也改变 所起的作用均是将变量tensor从原有的计算图中分
  • 解决Typora的测试版已过期问题 This beta version of Typora is expired, please download and install a newer versio

    错误提示 xff1a The beta version of typora span class token keyword is span expired span class token punctuation span please
  • WSL2 配置SSH 设置开机自启

    WSL2 配置SSH 设置开机自启 WSL2 配置SSH 设置开机自启先说结论完整wsl help WSL2 配置SSH 设置开机自启 尝试了很多博客上的方法没有找到理想的解决方案 xff0c 看了wsl help之后才知道这些方法确实十分
  • Undo Log学习

    一 Undo Log的作用 数据库故障恢复机制的前世今生中提到过 xff0c Undo Log用来记录每次修改之前的历史值 xff0c 配合Redo Log用于故障恢复 这也就是InnoDB中Undo Log的第一个作用 xff1a 1 事
  • 慢SQL解决方案

    一 全表扫描 1 案例 span class token keyword SELECT span span class token function count span span class token punctuation span
  • JAVA17新特性

    2022 年 7 月底 xff0c 甲骨文正式停止对Java SE 7的扩展支持 xff0c 一个有着近 11 年历史的 Java 标准版本迎来生命周期结束 目前最新版本的 Java18 于今年 3 月正式发布 xff0c 并将于 2022
  • 测试——单元测试,集成测试,系统测试,白盒,黑盒

    一 单元测试 1 何为单元测试 单元测试 xff08 unit testing xff09 xff0c 是指对软件中的最小可测试单元进行检查和验证 单元测试通常和白盒测试联系到一起 xff0c 如果单从概念上来讲两者是有区别的 xff0c
  • java对多媒体处理工具

    简介 JAVE Java Audio Video Encoder 类库是一个 ffmpeg 项目的 Java 语言封装 开发人员可以使用 JAVE 在不同的格式间转换视频和音频 例如将 AVI 转成 MPEG 动画 xff0c 等等 ffm
  • 线程池不允许使用Executors创建原因

    1 FixedThreadPool 和 SingleThreadPool 允许的请求队列长度为 Integer MAX VALUE xff0c 可能会堆积大量的请求 xff0c 从而导致 OOM span class token keywo
  • 高分子结晶的新进展、新模型

    高分子结晶的新进展 新模型 高分子的结晶结构与形态对高分子材料的物理机械性能具有重要影响 xff0c 高分子结晶过程的分子机理 结晶热力学 结晶动力学等构成了高分子物理的重要内容 高分子结晶的研究经历了从溶液培养单晶 xff0c 确定折迭链
  • wsl安装图形界面——体验有脸有面的图形界面

    不得不说 xff0c 自动windows支持linux子系统之后 xff0c 这又使其成为一大卖点 首先 Linux 的分发版本非常多 xff0c 例如有 xff1a Ubuntu openSUSE SUSE Linux Fedora Ka
  • E: 有未能满足的依赖关系。请尝试不指明软件包的名字来运行“apt --fix-broken install”(也可以指定一个解决办法)。

    国产银河麒麟系统下在使用apt install xxxxxxx 出现如下错误 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 您也许需要运行 apt fix broken install 来修正上面的错误 下列
  • 【CCF CSP-20160903】炉石传说

    CCF CSP 20160903 炉石传说 C 43 43 代码 span class token macro property span class token directive hash span span class token d
  • 树莓派介绍

    文章目录 一 树莓派介绍二 树莓派分类 一 树莓派介绍 树莓派 xff0c xff08 英语 xff1a Raspberry Pi xff0c 简写为RPi xff0c 别名为RasPi RPI xff09 是为学习计算机编程教育而设计 x
  • Docker核心技术-联合文件系统

    联合文件系统 xff08 UnionFS xff09 是一种分层 轻量级并且高性能的文件系统 xff0c 它支持对文件系统的修改作为一次提交来一层层的叠加 xff0c 同时可以将不同目录挂载到同一个虚拟文件系统下 联合文件系统是 Docke
  • Spark SQL与Hive SQL解析执行流程

    转载专用 xff1a 读到了好文章 xff0c 用于分享收藏 xff0c 侵权删 转发自大佬 xff1a 数据人生coding xff0c https yuanmore blog csdn net type 61 blog 转发自大佬 xf
  • 银河麒麟V10服务器系统安装教程及注意事项

    系统安装 1 引导安装 从U盘引导安装时首先进入的是安装引导页面 xff0c 如下图 xff1a 使用向上方向键 lt gt 选择 Install Kylin Linux Advanced Server V10 xff0c 按进入安装过程
  • 1012 - iOS之View Controllers的理解

    需求现在只是把navigationController的导航栏字体给去掉 xff0c 不过既然都看了 xff0c 那就直接刚一下吧 阅读官网文档的顺序 xff1a Managing Content in Your App 39 s Wind