ios - 我们应该使用 UIView 还是 UIViewController 来实现以下功能?
问题描述
我们有以下应用程序,用户可以在其中从侧面菜单切换到不同的“页面”(紫色、黄色、...颜色)。
我想知道,“页面”应该实现为UIView
,还是“页面”应该实现为UIViewController
?
页面应负责
- 从/向CoreData读取/写入。
- 可能持有 a
UIPageView
,用户可以在多个子页面中滑动,如https://i.stack.imgur.com/v0oNo.gif所示 - 拿着一个
UICollectionView
。 - 用户可以拖动和移动项目
UICollectionView
- 用户可以对
UICollectionView
. - 将来可以轻松移植到 iPad。
目前,我的使用实现UIView
如下。
private func archive() {
if let trashView = self.trashView {
trashView.removeFromSuperview()
self.trashView = nil
}
if self.archiveView != nil {
return
}
let archiveView = ArchiveView.instanceFromNib()
self.view.addSubview(archiveView)
archiveView.translatesAutoresizingMaskIntoConstraints = false
archiveView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
archiveView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
archiveView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
archiveView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
self.archiveView = archiveView
}
private func trash() {
if let archiveView = self.archiveView {
archiveView.removeFromSuperview()
self.archiveView = nil
}
if self.trashView != nil {
return
}
let trashView = TrashView.instanceFromNib()
self.view.addSubview(trashView)
trashView.translatesAutoresizingMaskIntoConstraints = false
trashView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
trashView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
trashView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
trashView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
self.trashView = trashView
}
我注意到,如果我使用 实现“页面” UIView
,我将失去一些UIViewController
类似的能力
viewDidLoad
打回来。viewWillLoad
打回来。viewDidLayoutSubviews
打回来。- ...
但是,我不清楚失去这些功能是否会阻止我实现正确的“页面”?
我可以知道,我应该使用UIView
还是使用 来实现那些“页面” UIViewController
?
解决方案
UIViewController
由于您已经在问题中列出的所有 UIKit 回调原因,我会这样做。
我假设您有一个为您的应用程序UINavigationController
设置的实例window.rootViewController
。您有一个对这个实例的引用,您可以使用它在不同的屏幕之间轻松切换。
例子
class SlideMenuViewController: UIViewController {
enum Option {
case archive
case trash
}
var onSelect: ((_ option: Option) -> Void)?
}
class ArchiveViewController: UIViewController {}
class TrashViewController: UIViewController {}
class AppNavigator {
let mainNavigationController: UINavigationController
init(navigationController: UINavigationController) {
self.mainNavigationController = navigationController
}
private lazy var slideMenuVC: SlideMenuViewController = {
let slideMenu = SlideMenuViewController()
slideMenu.onSelect = { [weak self] (option) in
self?.openScreen(for: option)
}
return slideMenu
}()
private lazy var archiveVC: ArchiveViewController = {
return ArchiveViewController()
}()
private lazy var trashVC: TrashViewController = {
return TrashViewController()
}()
func openScreen(for option: SlideMenuViewController.Option) {
let targetVC: UIViewController
switch option {
case .archive: targetVC = archiveVC
case .trash: targetVC = trashVC
}
mainNavigationController.setViewControllers([targetVC], animated: true)
}
}
推荐阅读
- git - git:查找文件的最新非重命名提交
- sql - 将联合查询重写为单个查询
- firebase - 如何使用 firebase google access token/id token 来访问 google api?
- react-native - 反应本机项目不会启动
- ruby-on-rails - 我有 Axios 和 Rails 的路由问题
- github - npm 安装失败 libp2p-websockets
- nginx - 524 多个连接超时错误
- javascript - 如何在javascript中显示弹出窗口之前验证复选框
- reactjs - 从 redux-saga 中的多个 firestore 引用中获取数据
- ag-grid - Ag Grid headerClass 覆盖 numericColumn 类型