在将IBOutlet用于UIViews时,如何在初始化期间引用self?

时间:2018-12-21 20:36:50

标签: swift iboutlet

我有一个自定义的UITableViewCell类,以表格视图的形式支持我的单元格(我从在UIKit团队的Apple的Andy Matuschak的演讲中学到了这种方法。

在我现在尝试应用的项目中,由于几个@IBOutlets链接到UIView元素上永远不会出现,因此初始化类时遇到了问题初始化时会获得类似UILabel的值:

class PublicationTableViewCell: UITableViewCell {

  @IBOutlet weak var publicationTitle: UILabel!
  @IBOutlet weak var authorName: UILabel!
  @IBOutlet weak var pubTypeBadgeView: UIView!
  @IBOutlet weak var pubTypeBadge: UILabel!
  @IBOutlet weak var topHighlightGradientStackView: UIStackView!
  @IBOutlet weak var bottomBorder: UIView!

  struct ViewData {
    let publicationTitle: UILabel
    let authorName: UILabel
    let pubTypeBadge: UILabel
  }

  var viewData: ViewData! {
    didSet {
      publicationTitle = viewData.publicationTitle
      authorName = viewData.authorName
      pubTypeBadge = viewData.pubTypeBadge
    }

  // I have @IBOutlets linked to the views so I can do this:
  override func setHighlighted(_ highlighted: Bool, animated: Bool) {
    super.setHighlighted(highlighted, animated: animated)

    if isSelected || isHighlighted {
      topHighlightGradientStackView.isHidden = true
      bottomBorder.backgroundColor = UIColor.lightGrey1
    } else {
      topHighlightGradientStackView.isHidden = false
    }
  }
}

extension PublicationTableViewCell.ViewData {
  init(with publication: PublicationModel) {

    // Xcode complains here about referring to the properties 
    // on the left before all stored properties are initialized

    publicationTitle.text = publication.title
    authorName.text = publication.formattedAuthor.name
    pubTypeBadge.attributedText = publication.pubTypeBadge
  }
}

然后我通过传递这样的出版物在cellForRow中对其进行初始化:

cell.viewData = PublicationTableViewCell.ViewData(with: publication)

Xcode抱怨我在self中使用init(with publication: PublicationModel)之前已经了解了所有存储的属性,但我不知道如何解决。

如果这些不是UIView属性,则可能使它们成为可选属性或计算属性,但是由于它们是IBOutlet,因此我认为它们必须是隐式展开的可选属性。

还有其他方法可以使它正常工作吗?

1 个答案:

答案 0 :(得分:0)

首先:

struct ViewData {
   let publicationTitle: String
   let authorName: String
   let pubTypeBadge: NSAttributedString
}

然后简单地:

extension PublicationTableViewCell.ViewData {
  init(with publication: PublicationModel) 
    publicationTitle = publication.title
    authorName = publication.formattedAuthor.name
    pubTypeBadge = publication.pubTypeBadge
  }
} 

这是一个数据模型,它不应该保存 views ,它应该只保存 data

然后:

var viewData: ViewData! {
    didSet {
       publicationTitle.text = viewData.publicationTitle
       authorName.text = viewData.authorName
       pubTypeBadge.attributedString = viewData.pubTypeBadge
   }
}

但是,我认为,如果您只是通过PublicationModel作为单元格数据,那会更简单。没有理由将其转换为另一个struct

var viewData: PublicationModel! {
    didSet {
       publicationTitle.text = viewData.publicationTitle
       authorName.text = viewData.authorName
       pubTypeBadge.attributedString = viewData.pubTypeBadge
   }
}