swift - 非可选 IBOutlet 返回 fatal error : when referenced from another UIViewController class

标签 swift uiview uiviewcontroller calayer

我在

中定义了一个 UIView
class InteractViewController: UIViewController {

    @IBOutlet weak var tipsView: UIView!
        var tipslayer: CALayer {
        return tipsView.layer
    }
}

类中还附加了许多约束以及标签。

@IBOutlet weak var tips1Top: NSLayoutConstraint!
@IBOutlet weak var tips1Right: NSLayoutConstraint!
@IBOutlet weak var tipsTitle: UILabel!
@IBOutlet weak var tipsDesc: UILabel!

所有内容都在 Storyboard上连接到它们正确的导出。在实际的 InteractViewController 本身中引用这些我能够调整不透明度,更新图层上的标签等。

但是,除非用户第一次使用该应用程序,否则不需要这些,因此 InteractViewController 上的一个简单的 if else 调用一个函数来显示和更新这些属性或根本不显示它们。

控制和更新这些属性的函数在另一个类中(调用的项目中的Swift文件。

class TipsViewController: UIViewController {

    func tips() {
        InteractViewController().tipslayer.transform = CATransform3DMakeScale(0.8, 0.8, 1.0)
    }
}

导致应用崩溃创建

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

return tipsView.layer (the InteractViewController)

tipsView 和 tipslayer 不是可选的,也没有声明为可选的。

我有三个问题希望能得到帮助。

  1. 对 ViewController 类 InteractViewController: UIViewController 上的 socket 的物理引用是否存在问题?如果是这样,是不是因为它们应该以编程方式添加到 TipsViewController 类中:UIViewController(Xcode 中没有物理可视 View Controller )?

  2. 是否对

    上的网点有物理引用

    类 InteractViewController: UIViewController

如果在 InteractViewController 上调用第二个 ViewContoller 上的函数 TipsViewController.tips() 从未被调用,那么创建不必要的内存使用,换句话说,问题 1 的答案基本上是任何物理 socket 都应该以编程方式添加到 lass TipsViewController:UIViewController ?

  1. 如果没有内存问题并且知道 tipsView 和返回的 tipslayer 不是可选的,为什么我无法从其他类(TipsViewController:UIViewController)的 tips() 函数中引用它们?我看过多篇关于“在 View Controller 之间传递数据”的帖子,但我没有在变量或数组之间传递数据。我想/需要简单地更新标签字符串、约束(一个 View Controller 类中的对象来自另一个 View Controller 类。

我知道人们很忙,所以提前说一下,我感谢所有反馈和对问题的帮助。

有人建议我的问题与 [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?

但这不是我的问题。我的问题具体涉及从另一个 ViewController 访问 Outlet,然后 ViewController 生成对 Outlet 的 Nil 响应,因为如前所述,InteractViewController 显然没有引用 ViewController。请阅读 Rob 提供的回答此特定问题的解释和答案。

最佳答案

您的标题说“IBOutlet 返回 fatal error :从另一个 UIViewController 类引用时”。底线是一个 View Controller 不应该访问另一个 View Controller 的导出。

在您的代码片段中,您使用了 InteractViewController() 语法。不幸的是,这只是实例化 View Controller ,但没有连接 Storyboard中的 socket 。您需要通过 Storyboard进行实例化,即便如此,您也不能立即引用您的 outlet,只能在稍后调用 viewDidLoad 之后引用。无论如何,只有 View Controller 本身应该尝试访问它自己的 socket 。

TipsViewController()InteractViewController() 语法表示“创建该 View Controller 的一个新的空白实例”。这相当于说 TipsViewController.init()InteractViewController.init()。而且,更糟糕的是,它根本没有使用 Storyboard(因此不会连接任何 socket )。那不是你想要的。您应该避免使用这种 ViewController() 语法,因为这样就永远无法访问 outlet。


InteractViewController 应确定是否应显示 TipsViewController(例如,检查用户默认值),如果是,则显示它。不过,InteractViewController 唯一应该做的是:

  • 确定是否呈现TipsViewController
  • 如果是,则显示 TipsViewController;和
  • 将模型数据(例如从 UserDefaults 检索到的任何 InteractViewController)传递给为您创建的 TipsViewController 实例。

但是关于 TipsViewController 如何呈现其 subview 的任何事情,都是 TipsViewController 的权限。 InteractViewController 永远不应与 TipsViewController 的任何导出直接交互。

关于swift - 非可选 IBOutlet 返回 fatal error : when referenced from another UIViewController class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53871380/

相关文章:

ios swift siesta ResourceObserver resourceRequestProgress 从未调用过

ios - 自定义 uiview 作为 inputview swift

ios - DismissViewController 关闭两个 UIViewController

swift - 在选项卡栏 View Controller 内执行操作后应用程序崩溃

当 subview 调整大小时,iOS LayoutSubviews 被多次调用

ios - 创建 ViewController 的单例对象

基于 iOS ADMOB 奖励的视频广告加载失败

UIAlert 之后 Swift 3 从 Struct 中退出

ios - TouchId 身份验证 - 删除警报

ios - 检测旋转的 UIView 之间的碰撞