带有tabBar 故事板 ID 的视图控制器不是标签栏控制器,您必须正确设置故事板 ID 才能使该代码正常工作。
首先,在故事板中将tabBarController id 设置为UITabBarController(见下图):
然后,将崩溃代码更改为:
let tabBar=storybaord.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
或者使用旧 ID tabBar - 但是你必须先在新闻视图控制器中更改它(我上传的图片中带有运动鞋图像的那个)。
无论如何,问题都很简单——您想从情节提要中实例化UITabBarController,但目前您的情节提要并未将其与tabBar ID 关联,但它将该ID 与不同的控制器关联。
编辑
总的来说,这个项目非常混乱。查看一些苹果开发者指南以获取命名和其他建议。
这里的问题是您正在混合使用 segues 导航(有一个用于点击单元格以打开标签栏的 segue)和编程导航(tableView's didSelectRowAt数据)。
所呈现的缺少图像和标题的视图是 segue 的结果。但是您没有为 segue 设置数据,这会导致您的问题。
您向我们展示的程序代码确实会执行,但没有用。应该弹出详细视图的DiscoveryNewsViewController 未嵌入在UINavigationController 中。因此以下行:
self.navigationController?.pushViewController(tabBar, animated: true)
未执行。在您的情况下,self.navigationController 包含 nil,因此该行不会被执行,并且不会显示带有图像和标题的详细视图。
你现在有两个选择。
选项 1 - 程序化方法
删除转场。在主情节提要中,单击DiscoveryNewsViewController 和UITabBarController 之间的转场,然后按删除。见下图:
然后在DiscoveryNewsViewController 中使用以下didSelectRowAt 实现来呈现细节:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storybaord=UIStoryboard(name: "Main", bundle: nil)
let tabBar=storybaord.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
let DVC = tabBar.viewControllers?[0] as! NewsViewController
tabBar.selectedIndex = 0
DVC.getImage=self.sneakersnews[indexPath.row].image
DVC.getNews=self.sneakersnews[indexPath.row].news
self.present(tabBar, animated: true, completion: nil)
}
请注意,我使用的不是self.navigationController?.pushViewController,而是self.present。
还将NewsViewController修改为:
class NewsViewController: UIViewController {
@IBOutlet weak var newsTitle: UILabel!
@IBOutlet weak var NewsImage: UIImageView!
var getNews=String() {
didSet {
newsTitle.text = getNews
}
}
var getImage=UIImage() {
didSet {
NewsImage.image = getImage
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
在属性上使用didSet 将正确设置图像和标题。在您在didSelectRowAt 中设置图像和标题之前,似乎已经调用了viewDidLoad。
选项 2 - 故事板方法
保持转场。将其标识符设置为showDetailSegue(见下图):
然后从DiscoveryNewsViewController中删除didSelectRowAt。
在出现之前使用prepare(for:sender:) 来配置NewsViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetailSegue",
let tabBar = segue.destination as? UITabBarController,
let DVC = tabBar.viewControllers?[0] as? NewsViewController,
let selectedRow = DiscoveryNewsTableView.indexPathForSelectedRow {
tabBar.selectedIndex = 0
DVC.getImage=self.sneakersnews[selectedRow.row].image
DVC.getNews=self.sneakersnews[selectedRow.row].news
}
}
请注意我正在使用
segue.identifier == "showDetailSegue"
在测试中确保我们正在处理的segue确实是我们想要处理的那个。在你的项目中只有这个 segue,所以它不是那么重要,但在一个更大的项目中,命名你的 segue 是一个好习惯。