ios - 如何在tabBarController中连接VC throw navController以快速传递数据
问题描述
当点击 tabBar 项时,我正在尝试更改 VC 中标签的文本。但是在我将 UINavigationController 嵌入到 VC 之后,我在点击 tabBar 时崩溃了(线程 1:致命错误:在隐式展开可选值时意外发现 nil)。有人知道如何解决吗?这是碰撞线的照片
import UIKit
class TabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 3{
let navVC = tabBarController.viewControllers![3] as? UINavigationController
let bagPageVC = navVC?.topViewController as? bagPage
bagPageVC!.stringCountOfHP = "\(String(bagPageVC!.countArray)) items in bag"
bagPageVC?.tableView.reloadData()
}
}
}
解决方案
这应该可以帮助您的代码避免崩溃,
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 3{
if let navVC = tabBarController.viewControllers?[3] as? UINavigationController,
let bagPageVC = navVC.topViewController as? bagPage {
bagPageVC.countOfHP.text = "\(String(bagPageVC.countArray)) items in bag"
}
}
崩溃可能有多种原因
1.tabBarController.viewControllers
可能返回零,
tabBarController.viewControllers![3] as! UINavigationController
尽管在索引 3 处存在视图控制器,但它可能不是UINavigationController
或子类UINavigationController
包页VC!可能为零,因此强制展开可能会使其崩溃,因为
navVC.topViewController
不是bagPage
如果不正确查看您的 ViewController 设置 n 层次结构,则无法为您提供更多帮助。
上面的代码将安全地解开所有的选项,所以它不会让你的代码崩溃
编辑1:
问题第一次发生,当您点击索引 3ViewController
处的选项卡栏时,该索引在屏幕上尚不可见,因此显然它的所有IBOutlet
s 都为零,并且当您盲目访问隐式可选 IBOutletbagPageVC.countOfHP
时,它会崩溃。
你能做什么?
我能想到的两种可能的解决方案
解决方案1:
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 3,
let bagPageVC = (viewController as? UINavigationController)?.topViewController as? bagPage {
let _ = bagPageVC.view //this statement will force the view controller to load its view hence `ViewDidLoad` will be called automatically for the first time (which anyway would have called you are just fast tracking it
bagPageVC.countOfHP.text = "\(String(bagPageVC.countArray)) items in bag"
}
}
didSelect viewController
每次用户选择不同的选项卡时都会被调用,但let _ = bagPageVC.view
只会ViewDidLoad
被调用一次(一旦加载视图,当您访问.view
它时只会返回视图)
虽然这段代码可以正常工作,没有任何问题,但我不太喜欢干预 View 周期,因此解决方案 2
解决方案2:
检查隐式可选IBOutlet
是否为nil
,如果不是,则简单地设置文本,否则将文本传递给bagPageVC
并将其设置为ViewDidLoad
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 3,
let bagPageVC = (viewController as? UINavigationController)?.topViewController as? bagPage {
if let countLabel = bagPageVC.countOfHP {
countLabel.text = "\(String(bagPageVC.countArray)) items in bag"
}
else {
bagPageVC.countInfo = "\(String(bagPageVC.countArray)) items in bag"
}
}
}
现在在您bagPageVC
声明一个名为的countInfo
变量String?
var countInfo: String? = nil
你ViewDidLoad
可以简单地设置
override func viewDidLoad() {
super.viewDidLoad()
countOfHP.text = countInfo
}
ViewDidLoad
在 ViewController 的生命周期中只被调用一次,因此您不必担心countInfo
在后续didSelect viewController
调用中重置
你会选择哪一个我留给你:)
推荐阅读
- c# - 如何在dockerfile中复制引用项目的.csproj
- javascript - Angular 7获取关键字列表的谷歌搜索结果计数
- c++ - 显式模板实例化问题
- moodle - Moodle:带有链接的开放课程
- nginx - set_real_ip_from 仍然包含在 HTTP_X_FORWARDED_FOR 中
- java - Java计算字符串相似度的最佳算法
- akka - 如果使用 `ask` 模式而不是 `tell` 模式,Akka ShardRegion 会成为性能瓶颈吗?
- kotlin - 领域(kotlin):查询具有至少一个孩子具有非空字段的孩子列表的对象
- algorithm - 从 1 到 k 中选择数字使其总和等于 n 的方法有多少?
- r - 如何创建行的子集,直到条件为 False 并继续这样做?