ViewController 加载两次
Posted
技术标签:
【中文标题】ViewController 加载两次【英文标题】:ViewController loading twice 【发布时间】:2016-12-27 15:44:11 【问题描述】:我正在使用目标 C 和 swift 3 的组合。
在我的 mainView(目标 C)中,我有以下内容
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:[NSBundle mainBundle]];
CourseViewController *courseView = (CourseViewController*)[storyboard instantiateViewControllerWithIdentifier:@"courseView"];
[self.navigationController pushViewController:courseView animated:YES];
在我的故事板中,我的 mainView 将显示一个导航控制器,它是 swift 3 视图的 rootView。
在 swift 3 视图控制器中,我有以下内容,并且 loadView 和 viewDidLoad 被调用了两次
override func loadView()
webView = WKWebView()
//If you want to implement the delegate
webView?.navigationDelegate = self
view = webView
override func viewDidLoad()
super.viewDidLoad()
let temp: CGRect = UIScreen.main.bounds
screenSize = temp
let url = URL(string: kcourseURL)
let req = URLRequest(url: url!)
webView.allowsBackForwardNavigationGestures = true
webView.load(req)
//webView.frame = CGRect(x:0, y:navBarHeight, width:Int(screenSize.width), height:Int(screenSize.height))
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
self.setBarButton()
关于为什么它被调用两次的任何建议?
另外,我试图关闭此视图以返回主视图,但如果我在 swift 3 视图上使用导航控制器,它不会被调用。我试过以下。我是否需要使用 segue unwind 来返回主视图?
self.dismiss(animated: true, completion: nil)
_ = self.navigationController?.popToRootViewController(animated: true)
【问题讨论】:
在使用 Storyboard 时,为什么要显式实例化视图控制器? 你在Storyboard
的两个viewControllers 之间设置了一个segue 吗?
我在故事板的 2 个视图之间设置了 segue。课程视图有一个导航控制器作为根视图。我明确地实例化视图,因为我在目标 c 中这样做,不知道当我对 Swift 实现执行目标 c 时它会如何变化。如果我不实例化它,则不会仅通过情节提要设置调用视图。
【参考方案1】:
如果您在应用程序导航控制器中使用,那么如果您使用 Segue 进行导航,我需要在此处清除一件事,那么在 的帮助下无需再次调用相同的视图>code 在这里只选择一个进程。导航将取决于您想要哪种类型,例如推送、显示、模态呈现和弹出框呈现。
之后只需要使用一行来返回视图或返回根视图:-
self.dismiss(animated: true, completion: nil)
或
_ = self.navigationController?.popViewController(animated: true)
或 用于返回 Rootview
_ = self.navigationController?.popToRootViewController(animated: true)
对于导航,一个故事板到另一个故事板:-
Objective-C
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
SecondViewController *second = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
[self.navigationController pushViewController:second animated:YES];
斯威夫特 3
let storyboard = UIStoryboard(name: "Customer", bundle: nil)
let secondVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
self.navigationController!.pushViewController(secondVC, animated: true)
并尝试使用 Segue
首先需要获取storyBoard 引用,然后添加storyBoardname,然后在Referenced Id 中添加ViewController 的StoryBoard ID。
并确认您的目标控制器的Storyboard ID
最后使用数据segue标识符执行Segue:-
let segueIdentifier = "fourthView"
//MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == segueIdentifier
let controller = segue.destination as! FourthVC
//Passing Values here
controller.promoViewModel = promotionModel[0]
输出将如下图所示,无需做任何额外的事情:-
【讨论】:
我正在使用 segue,在 Perform segue 中,我调用以下 UIStoryboard storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:[NSBundle mainBundle]]; CourseViewController *courseView = (CourseViewController)[storyboard instantiateViewControllerWithIdentifier:@"courseView"]; [self.navigationController pushViewController:courseView 动画:YES]; 我已经尝试了所有这 3 种方法,但它不会关闭并返回根视图。如果我不使用导航视图作为根视图,那么这些都可以工作,但是我会丢失所有按钮的导航栏 您在同一个故事板或另一个故事板中执行segue?如果您在这里执行从一个故事板到另一个故事的转场,我将更新我的答案。 谢谢。看起来我唯一需要的是 [self performSegueWithIdentifier:@"training" sender:self];然后故事板中的一个segue称为训练。我在 prepareForSegue 中添加了另一个调用,它再次触发了视图。感谢您的帮助!【参考方案2】:检查您是否在哪里调用了loadView()
方法,因为您的代码并非全部发布,如果是:
你不应该直接打电话给loadView()
,根据苹果的doc
你不应该直接调用这个方法。视图控制器在其视图属性被请求但当前为 nil 时调用此方法。此方法加载或创建视图并将其分配给视图属性。
如果视图控制器具有关联的 nib 文件,则此方法从 nib 文件加载视图。如果 nibName 属性返回非 nil 值,则视图控制器具有关联的 nib 文件,如果视图控制器是从情节提要中实例化的,如果您使用 init(nibName:bundle:) 方法显式为其分配了一个 nib 文件,则会发生这种情况,或者如果 ios 在应用程序包中找到一个名称基于视图控制器的类名的 nib 文件。如果视图控制器没有关联的 nib 文件,则此方法将创建一个普通的 UIView 对象。
如果子类不使用 nib,则应在此处创建自定义视图层次结构。永远不应该直接调用。
无论你为 Xib 加载视图还是自己创建视图,viewDidLoad
总是会在视图加载完成后被调用。
把你的代码放在下面:
webView = WKWebView()
//If you want to implement the delegate
webView?.navigationDelegate = self
view = webView
从loadView()
到viewDidLoad()
,并删除loadView()
方法。
编辑 - 1
我写了一个演示来测试你的混合项目,我发现它不是因为loadView()
,我尝试使用perform segue
并使用navigationController push
,没有工作,所以我的答案不适合你,我我发现为什么混合演示中有问题,奇怪。
【讨论】:
我看不到问题中loadView()
的调用位置。
我没有调用 loadView,它是自动调用的。但在我的实现中,loadView 和 viewdidload 被触发了两次,所以我的视图加载了两次。以上是关于ViewController 加载两次的主要内容,如果未能解决你的问题,请参考以下文章