ios - TabBarController 的第二个选项卡未实例化 -> IBOutlets 为 nil

标签 ios swift uitabbarcontroller iboutlet

我正在创建一个简单的应用程序,它有一个选项卡栏 Controller ,其中摘要是一个选项卡,历史记录是另一个选项卡。在摘要选项卡中,有一个用于添加新回合的按钮。每当添加这一轮时,它也必须转到历史选项卡。

我正在尝试通过 tabBarController 发送数据。

我遇到的情况是,每当我在添加新一轮之前不打开历史选项卡时,我的程序就会崩溃,因为我的 IBOutlets 为零。但是每当我先打开选项卡然后返回添加新回合时,它都可以正常工作。我也不必在每一轮之后重新打开选项卡。在我第一次打开它之前,该选项卡似乎没有被实例化。

失败动图(错误是图表View为nil): http://i.imgur.com/VPa0RmK.gifv

成功的动图: http://i.imgur.com/LqxYBjV.gifv

有什么办法可以手动完成吗?

我是 iOS 编程的新手,所以我认为这就是问题所在。如果发生其他导致我的代码崩溃的事情,我想知道!

最佳答案

你是对的。问题是第二个选项卡的 socket 在您访问该选项卡之前不会设置。

解决方案:

  1. 您可以将数据写入第二个 viewController 的属性,然后将该数据移动到覆盖 viewWillAppear 的 socket 中。

  2. 另一种可能性是在写入之前检查导出是否为 nil。如果是,请在第二个 viewController 上调用 loadView 以告诉它设置其 outlet,然后您就可以向它们写入数据。请注意,如果您手动调用 loadView,方法 viewDidLoad 将不会运行,因此如果您在那里进行任何其他设置,您还需要这样做来自 loadView

  3. 也许比手动调用 loadView 更简单的方法是通过访问 view 属性来触发 secondViewController 的 viewDidLoad。这可以很简单:

    if let svc = self.tabBarController?.viewControllers?[1] as? SecondViewController {
        // check if outlet is nil
        if svc.myLabel == nil {
            // trigger viewDidLoad to set up the outlets
            _ = svc.view
        }
        svc.myLabel = "Success!"
    }
    
  4. 也就是说,直接访问另一个 viewController 的 View (即 socket )是糟糕的设计,并且违反了 MVC(模型- View - Controller )范例。您真的应该将数据放在所有选项卡都可以访问的地方,然后在选择选项卡时让每个 viewController 在 viewWillAppear 中自行更新。看到这个答案:Sharing data in a TabBarController一种方法。

关于ios - TabBarController 的第二个选项卡未实例化 -> IBOutlets 为 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40829520/

相关文章:

ios - 具有自定义委托(delegate)或数据源的 View Controller 的状态保存

ios - Flutter Firebase 回调不会在 iOS 13 上触发,但在 Android 上可以正常工作

ios - UIMenuController 和 TapGesture 在移动时重新出现

iphone - "Reuse"UITabBarController 中的 UITableViewController

objective-c - iOS底部标签栏标题

ios - 选项卡栏图像在 Storyboard中显示良好,但在模拟器中显示不佳

php - iOS gzip 压缩到 PHP

ios - 如何在 collectionView 之上使用 UIView,以便当我滚动单元格时,UIView 不应该移动?

ios - 如何检测非侵入式电话

swift - watchOS LTE 与 iPhone 应用程序通信