我在
中定义了一个 UIViewclass 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 不是可选的,也没有声明为可选的。
我有三个问题希望能得到帮助。
对 ViewController 类 InteractViewController: UIViewController 上的 socket 的物理引用是否存在问题?如果是这样,是不是因为它们应该以编程方式添加到 TipsViewController 类中:UIViewController(Xcode 中没有物理可视 View Controller )?
是否对
上的网点有物理引用类 InteractViewController: UIViewController
如果在 InteractViewController 上调用第二个 ViewContoller 上的函数 TipsViewController.tips() 从未被调用,那么创建不必要的内存使用,换句话说,问题 1 的答案基本上是任何物理 socket 都应该以编程方式添加到 lass TipsViewController:UIViewController ?
- 如果没有内存问题并且知道 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/