UIKit — 带有 ViewCode 的基本导航层次结构
UIKit — 带有 ViewCode 的基本导航层次结构
创建屏幕层次结构并在它们之间轻松导航
当我们实现一个应用程序时,尤其是当它的设计不包含标签栏时,我们希望以某种方式确保用户可以在不同的屏幕之间移动以使用它的功能。使用 Storyboard,这非常简单:按下一个命令,拉一个箭头,就是这样,两个具有不同 ViewController 的屏幕连接起来并可以相互导航。
但是当我们使用 ViewCode 的时候呢?真的有那么难吗?答案是 不 ,这里是 很短 逐步实现一个简单的层次结构:
0.相关词汇
- UINavigationController : 为我们抽象层次结构的现成 UIKit 控制器
- @objc func(Objective-C 类型函数) : 在 UIButtons 上调用的函数,例如按下时
- 弹出视图控制器: 从导航堆栈的顶部移除屏幕(当前正在显示),然后显示返回到前一个
- 推视图控制器: 将画布添加到堆栈顶部并显示到它
1.建立层次的根
我们需要定义母亲是谁,或者特定层次结构的起点。
假设我的应用程序有一个 入职 ,一旦用户退出它,我想要启动画面或 家 开始一个层次结构。
_班级_ 入职页面控制器:UIViewController { // 创建回家的按钮
让 goToHomeButton() = {
让按钮:UIButton(类型:.roundRect)
button.addTarget(self, action: #selector(goToHome), for: .touchUpInside)
}() // 实现按钮按下时调用的函数 @ _对象_ _私人的_ _功能_ 回家() {
_让_ rootViewController = HomeViewController()
_让_ 导航= UINavigationController(rootViewController:rootViewController)
nav.modalPresentationStyle = .fullScreen present(nav, animated: true) // 只定义会有动画和屏幕完整的行
}
}
这样,只要我按下去主页,我就会初始化一个 UINavigationController(带有变量名 导航 ) 并作为您的控制器传递 根即rootViewController, 的一个实例 主视图控制器 (), 我 我建立 它控制着我的家。
准备好了,我们定义 HomeViewController 是导航的根。现在,让我们看看如何在 Home 之后添加另一个要访问的屏幕。
2.向层次结构添加屏幕
我想从主屏幕转到下一个屏幕,我们将调用它 行动一 ,它有自己的控制器,称为 actionOneViewController .为此,我将使用该功能 推视图控制器 并将其作为我点击 nextButton 按钮时要调用的操作。
类 HomeViewController: UIViewController {
让 **下一个按钮** () = {
让按钮:UIButton(类型:.roundRect)
button.addTarget(self, action: #selector(nextButtonAction), for: .touchUpInside)
}() @objc func nextButtonAction(_ sender: UIButton) {
让 **下一个视图控制器** = actionOneViewController()
**导航控制器** ?. **导航栏.tintColor** = .white // 这一行只是定义了自动创建的导航栏的样式 // **导航控制器** ?. **推视图控制器** ( **下一个视图控制器** ,动画:真)
}
}
实例化 actionOneViewController 并将其作为 范围 从 pushViewController 方法中,我添加了我的控制器 到导航堆栈的顶部 .换句话说,我的新控制器变成了画布 显示 在设备上,如果用户想返回,这个控制器将是第一个 从堆里出来 ,显示之前的屏幕 以下 她。这说得通?
3. 返回上一画面
让我们这样做:返回上一个屏幕。如果我所在的屏幕总是我的堆栈顶部,如果我想返回 到它之前的屏幕 , 它只是 从堆栈中删除当前画布 并且将显示上一个。这是 popViewController 方法,而不是 push。
我在哪里可以设置这个?你看,当我们创建层次结构时,UIKit 自动提供了一个 导航栏 这将显示 默认情况下为“返回”选项。 该按钮将由 UINavigationController 自动生成,其特性可在函数中更改 viewDidLoad 我们想要离开的 ViewController。
( ** 观测值** :您可以发送另一个按钮,而不是 UINavigationController 给出的默认按钮,也可以弹出它!只需使用步骤 2 中相同的 @objc func 并将 push 更改为 pop,并将 nextViewController 更改为您要退出的当前控制器)
Nesse exemplo, há também a opção "Done", que não aparece no nosso caso, e o "Back" foi customizado com o título "Previous VC"
覆盖 func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: “”, style: .plain, target: nil, action: nil)
}
在上面的示例中,我希望按钮没有标题,只是返回箭头图标。它将是白色的,正如我们在步骤 1 中定义的那样,navigationBar 颜色 = .white。
我们称 . 自己 首先,然后我们可以移动 导航项 ,特别是在它返回的内容中,即 backBarButtonItem .这一切都是生成的 自动地 UINavigationController 为我们服务;)
4. 好的,如果我想返回 2 个屏幕怎么办? ❓
您可以 返回任意数量的屏幕 ,直到你找到根!你不必只去上一个。为此,你 不能使用流行音乐 ,因为 pop 总是删除堆栈顶部的画布。
您将不得不调用该方法。 消除。 请参见下面的示例,其中我想要 3 个屏幕,我在 3 号,我想直接跳到 1 号。
(考虑到这段代码在 viewDidLoad 从我的第三个屏幕)
让 previousViewControllerIndex = navigationController.viewControllers.count — 2
navigationController.viewControllers.remove(at: previousViewControllerIndex)
注意调用值 .viewControllers 从导航控制器返回一个 所有控制器的数组 在我的堆栈上,索引从 [0] 到 [total screen — 1]。第一个索引 0 始终是根,而最后一个始终是我现在所在的位置。
这样,如果我想在我打开屏幕之前立即获得屏幕的值,我可以通过从总屏幕值中减去 2 来实现。这就是我在第一行所做的,将该值存储在一个名为 上一个视图控制器索引 .
从那里,我可以使用 .remove 删除并传递我计算的这个索引作为参数。所以,当我按“返回”时,它不会转到旧的上一个屏幕,因为它是 从层次结构中移除 !它将跳过上一个屏幕,在本例中为第 2 个屏幕,直接进入第 1 个屏幕。
更多使用方式。 消除 , 去 esse 链接做 Stack Overflow .
就是这样。希望这个简短的介绍有所帮助!您可以将任意数量的 viewController 添加到此层次结构中, 推弹 一样的。研究命名数据结构 电池 有助于更直观地理解这个想法,但它非常简单。
到下一个 :)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明