从另一个类访问 IBOutlet
Posted
技术标签:
【中文标题】从另一个类访问 IBOutlet【英文标题】:Accessing an IBOutlet from another class 【发布时间】:2014-07-24 14:22:30 【问题描述】:我是 Swift/ios 新手,请多多包涵:
我正在尝试从另一个类访问一个类中的函数,并更新 UIImage 名称。
在我的视图控制器类中,我有
class Documents: UIViewController, UITableViewDataSource, UITableViewDelegate
@IBOutlet var UpdateImage: UIImageView
override func viewDidLoad()
super.viewDidLoad()
UpdateImage()
func UpdateImage()
UpdateImage.image = UIImage(named: "NewImage")
一切正常,图片更新为“NewImage”
问题:我可以从另一个类访问 UpdateImage func,但为什么在尝试更改 Documents 类中的图像时会产生错误?
class GetChanges
var success = operation:AFHTTPRequestOperation!, response:AnyObject!) -> Void in
var MakeChange = Documents()
MakeChange.UpdateImage()
这会在 Documents 类中的 "UpdateImage.image = UIImage(named: "NewImage")" 上生成错误; “致命错误:在展开可选值时意外发现 nil”
【问题讨论】:
【参考方案1】:当您在类本身中调用它时,它会在自身上运行,并且已经从 nib/storyboard 创建。这意味着UpdateImage
存在。
当你从另一个类调用方法时,当你调用这一行时:
var MakeChange = Documents()
您正在创建Documents
的新实例。这不是通过 nib/storyboard 初始化的,因此它从未填充 IBOutlet
值 UpdateImage
。因为这个值不存在,所以意外找到nil
并抛出错误。
您需要以某种方式保留对您尝试显示的Documents
实例的引用。我需要更多信息来告诉你如何做到这一点。
另外,因为您提到您是新人,所以我想指出一些我注意到您的代码的问题,这些问题使得阅读变得非常困难。
大写名称保留给Types
变量名称不应(几乎)以大写字母开头。
变量名称应该反映它们所代表的对象。 UpdateImage
听起来像是一张图片。最好把这个命名为updateImageView
函数也应该是小写的。以这种方式看到大写很奇怪,并且使代码读起来有点不舒服。
祝你好运!
【讨论】:
感谢 cmets re:我的代码的可读性,我来自另一种语言,所以我会继续观察这些问题......但这并不能真正解决我遇到的问题. @MrSparkle2014 我想了很多,但是我的 cmets 对维护对Documents
特定实例的引用有帮助吗?
不,很遗憾它对我没有帮助。
@MrSparkle2014 - 没有理由时髦,我只是想帮忙。我特别告诉过你,如果你需要帮助来解决你的问题,我需要更多信息。没有人可以用给定的信息回答你的问题,因为你不理解这个概念。如果您需要帮助,请按照我提供的详细说明。没有其他人回答这个问题是有原因的,这与我的回答无关。【参考方案2】:
了解 View Contoller 的生命周期,这对 iOS 开发者来说是非常重要的知识。
正如洛根所说:
您正在创建 Documents 的新实例。这不是通过 nib/storyboard 初始化的,因此它从未填充 IBOutlet 值 UpdateImage
这意味着在调用 init
for ViewController(即Documents()
)nib
后未加载。只有在 viewDidLoad
阶段之后,您才能在另一个代码中使用 viewController 的出口。 Apple docs:
您指定的 nib 文件不会立即加载。它在第一次访问视图控制器的视图时加载。如果您想在加载 nib 文件后执行其他初始化,请覆盖 viewDidLoad() 方法并在那里执行您的任务。
您可以删除MakeChange.UpdateImage()
,因为它将在viewDidLoad
中调用。或者,如果您想将特定图像名称传递给视图控制器:
class Documents: UIViewController, UITableViewDataSource,
UITableViewDelegate
@IBOutlet var UpdateImage: UIImageView
var imageName: String?
override func viewDidLoad()
super.viewDidLoad()
updateImageView()
func updateImageView()
if let imageName = imageName
UpdateImage.image = UIImage(named: imageName)
之后就可以使用了
let documentsViewController = Documents
documentsViewController.imageName = "newImage"
当你加载documentsViewController时,会出现newImage
【讨论】:
以上是关于从另一个类访问 IBOutlet的主要内容,如果未能解决你的问题,请参考以下文章