【问题标题】:UIImageView outlet nil in custom UIView with xib带有 xib 的自定义 UIView 中的 UIImageView 出口为零
【发布时间】:2019-06-04 17:03:19
【问题描述】:

我创建了一个自定义 UIView,其中包含多个 IBOutlets,包括一个 UIImageView 和三个 UILabels。尽管在 awakeFromNib() 函数中设置了图像值,但在尝试设置它时,我仍然得到插座的 nil 值。 UIView 是使用自定义 xib 文件构建的。

我将设置操作放在awakeFromNib() 中,以确保在设置插座之前已对其进行了初始化,但这没有帮助。我不确定是否是 xib 文件的问题,因为我在制作自定义表格单元格时只使用过自定义 xib,所以问题可能出在那儿?

class VotingCard: UIView {
    @IBOutlet weak var proPicImg: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var hometownLabel: UILabel!
    @IBOutlet weak var ratingLabel: UILabel!

    var proPic = UIImage()
    var name = ""
    var hometown = ""
    var rating = 0.0

    init(pic: UIImage, rush: Rush) {
        proPic = pic
        name = rush.fullName
        hometown = rush.homeTown
        rating = rush.compositeRating
        super.init(frame: CGRect(x: 0, y: 0, width: 250, height: 300))
    }

    override func awakeFromNib() {
        proPicImg.image = proPic
        nameLabel.text = name
        hometownLabel.text = hometown
        ratingLabel.text = "\(rating)"
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

我应该查看一张包含个人资料图片和相应数据的简单卡片,但它却崩溃了。

【问题讨论】:

  • 你是如何实例化你的视图的?
  • 让 v = Bundle.main.loadNibNamed("VotingCard", owner: self, options: nil)!.first as! VotingCard,然后我用这个对象设置各种属性(不是 iboutlets 本身,而是它们所在位置的变量),在 awakeFromNib() 中我将出口值设置为这些变量的值
  • 尝试创建一个新的 XIB 和类,不要使用旧的任何东西,意味着不要从头开始复制标签或图像之类的任何东西。

标签: ios swift xcode uiview xib


【解决方案1】:

你的问题是

1-imageView 没有连接到 Ib ,解决方法是连接它

或者

2- 您使用 init(pic: UIImage, rush: Rush) { 创建视图的对象,并且肯定不会使用 view 加载 UI,因此所有 outlet 都是 nil ,以及添加此方法的修复

class func getInstance(_ pic: UIImage, rush: Rush) -> VotingCard { 
   let v = Bundle.main.loadNibNamed("VotingCard", owner: self, options: nil)!.first as! VotingCard 
   v.proPic = pic
   v.name = rush.fullName
   v.hometown = rush.homeTown
   v.rating = rush.compositeRating
   return v
}

打电话

let v = VotingCard.getInstance(<#image#>,rush:<#rush#>)
v.frame = // set some frame
// ready for use

【讨论】:

  • 一个问题解决了另一个问题,我现在收到错误,这个类与键___的键值编码不兼容。我知道这个错误是由不良的插座连接引起的,但我现在已经多次删除并重新创建了我的 xib 连接,但问题仍然存在。
  • 深入查找该键名,并搜索所有网点
  • 还有其他问题会导致这种情况发生吗?我发现当我简单地移除了麻烦的插座时,我只是在下一个插座时遇到了同样的错误,我完全移除了所有插座并且未能解决它所以我想知道是否有一些我遗漏的基本错误我的 xib 文件
  • 确保分配类并从头拖动所有出口
  • 是的,类是正确的,再次尝试连接,仍然没有运气。
【解决方案2】:

编辑

基于 NIB 的开发在某种程度上已被弃用:

对于 iOS 开发人员,推荐使用故事板进行设计 用户界面。

https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/NibFile.html

但是,您似乎缺少这一步:

在运行时,您使用loadNibNamed:owner: 方法加载一个 nib 文件 或其变体。文件的所有者是 nib 中的占位符 您作为所有者参数传递的对象的文件 方法。无论您建立与文件的任何连接 Interface Builder 中的 nib 文件中的所有者在您重新建立时 在运行时加载文件。

看一个例子:

https://medium.com/@umairhassanbaig/ios-swift-creating-a-custom-view-with-xib-ace878cd41c5

如果您想使用 Storyboard 的推荐方式(显然不是,但这适用于普通观众):

https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html

viewDidLoad()——当视图控制器的内容视图(顶部 它的视图层次结构)是从情节提要中创建和加载的。这 视图控制器的出口被保证具有有效值 调用此方法的时间。使用此方法执行任何额外的 视图控制器所需的设置。

因此,使用UIViewController 方法,请将您的代码放在viewDidLoad() 中。

请记住,这是总是调用的,因此这将覆盖您的自定义 init() 函数的工作。也许这就是你遇到的问题。

我会重构它以避免丑陋的代码。始终创建 Rush 对象(声明为 Optional 作为存储属性),但在 XIB 情况下在 awakeFromNib() 中对其进行初始化,并在 custom-init 情况下复制输入对象。

那么viewDidLoad() 没有条件。

【讨论】:

  • 这是有道理的,但我的意图是制作自定义 UIView,而不是 UIViewController,而且我相信 UIView 没有 viewDidLoad()
猜你喜欢
  • 2013-10-21
  • 1970-01-01
  • 2015-04-17
  • 2018-06-15
  • 1970-01-01
  • 2016-01-27
  • 2023-04-02
  • 2013-10-08
  • 1970-01-01
相关资源
最近更新 更多