我正在研究多个框架,而我的问题只是一个“哲学的”问题。
我创建了一个实用程序功能来显示视图控制器
static func presentViewController(identifier: String, storyboardName: String = "Main", presentationStyle: UIModalPresentationStyle = .fullScreen){
let storyboard = UIStoryboard(name: storyboardName, bundle: InternalConstants.bundle)
var viewResult: UIViewController
if #available(iOS 13.0, *) {
viewResult = storyboard.instantiateViewController(identifier: identifier)
} else {
viewResult = storyboard.instantiateViewController(withIdentifier: identifier)
}
viewResult.modalPresentationStyle = presentationStyle
var top = UIApplication.shared.keyWindow?.rootViewController
while top?.presentedViewController != nil {
top = top!.presentedViewController
}
top!.present(viewResult, animated: true, completion: nil)
}
首先,这是呈现视图控制器的正确方法还是有更好的方法?
然后,最好在导航控制器中显示视图控制器吗?
答案 0 :(得分:2)
首先,是呈现视图控制器的正确方法还是更好的方法?
代替实用程序放入
.ONESHELL:
那么,是否最好在导航控制器中显示视图控制器?
导航是面向推送/弹出的,但是使用它来呈现另一个vc也没有错
答案 1 :(得分:1)
首先,这是呈现视图控制器的正确方法还是有更好的方法?
只要它正常工作,那是对的,这只是您做此特定事情的方式,但是就iOS
和UIKit
而言,这样做是否正确,答案通常是通过查看rootViewController's
presentedViewController
来呈现viewController是一件坏事,因为它不能保证您找到的最后一个presentedViewController
是一件好事,而且您不会知道直到崩溃为止,presentedViewController
可能是UISearchController
,并且如果您从情节提要中使用UIContentContainer
或ContainerView
,则可能会有一个小的{{1} },这可能不利于viewController的出现和消失
您将面临的另一个问题是,当您需要通过使用这种方法向呈现的viewController传入和传出数据时,甚至都没有对呈现的viewController的引用,因为您只传递了{ {1}}
从UISlider
的角度出发,您永远不要尝试通过直接从视图中调用函数来从identifier
呈现viewController 那是不好的习惯
如果您尝试使用MVC
SDK来展示任何系统UIView
,就会发现您有责任实例化并展示vc,例如UIKit
,UIViewController
,UIImagePickerController
,UIActivityViewController
,UIDocumentPickerViewController
,UIDocumentMenuViewController
Apple本身并没有提供提供其系统vcs功能的功能
相反,如果您正在开发框架并且不想让用户访问您的viewControllers,则应使您拥有自己的窗口并为其赋予一个UIPrinterPickerController
Apple也为此提供了许多示例,出于安全原因,在UIVideoEditorController
框架中,您不应引用safari Web浏览器,而是使用名为rootViewController
的东西来控制演示和展示的流程。通过调用AuthenticationServices
和ASWebAuthenticationSession
函数关闭Safari Web ViewController
您框架的用户也不总是希望使用默认的演示动画来展示viewController,他们可能希望使用自定义viewContollers动画,他们需要访问viewController上的start()
属性
想象如果您采用这种方法,将无法访问cancel()
上的每个公共有用属性
然后,最好在导航控制器中显示视图控制器吗?
至于这部分,最好在NavigationController上显示任何内容
故事板头痛 关于情节提要板初始化的麻烦,有很多文章讨论如何优化情节提要板初始化调用网站,我建议您这样做
transitioningDelegate
通过这种方式,您可以使用UIViewController
初始化情节提要,以改善呼叫站点,就像这样
extension UIStoryboard {
enum AppStoryBoards: String {
case
login,
main,
chat,
cart
}
convenience init(_ storyboard: AppStoryBoards, bundle: Bundle? = nil) {
self.init(name: storyboard.rawValue.prefix(1).capitalized + storyboard.rawValue.dropFirst(), bundle: bundle)
}
}
然后您可以使用另一个扩展程序来初始化视图控制器
enum
然后您可以这样称呼它
let login = UIStoryboard.init(.login)
或此
extension UIStoryboard {
func instantiateInitialVC<T: UIViewController>() -> T {
return self.instantiateInitialViewController() as! T
}
func instantiateVC<T: UIViewController>(_: T.Type) -> T {
return self.instantiateViewController(withIdentifier: String(describing: T.self)) as! T
}
}
这样做可以改善用于显示任何viewController的整体代码
let loginVC = UIStoryboard.init(.login).instantiateInitialVC()