Swift 3: настраиваемая ячейка табличного представления

У меня возникли проблемы с визуализацией моей пользовательской ячейки табличного представления в построителе интерфейса.

Кто-нибудь знает, как сделать ячейку представления таблицы @Designable?

Когда я импортирую свою пользовательскую ячейку табличного представления в раскадровку с табличным представлением, работает только цвет фона. Когда я пытаюсь установить текст метки внутри ячейки табличного представления, происходит сбой построителя интерфейса.

Моя установка вызывается из следующих методов:

- override public init(style: UITableViewCellStyle, reuseIdentifier: String?)

- required public init?(coder aDecoder: NSCoder)  

Я думаю, это потому, что моя метка в данный момент не инициализирована?

Код:

import UIKit

@IBDesignable class ProgressHeaderTableViewCell: UITableViewCell {

    @IBOutlet weak var headerLabel: UILabel!

    // MARK: - View methods

    override public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.setupNib()
    }

    // MARK: - NSCoding
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setupNib()
    }

    func setupNib(){
        self.backgroundColor = UIColor.blue

//        self.headerLabel.text = "Hello world"
    }

}

Обновлен код:

import UIKit

@IBDesignable class CustomTableView: UITableViewCell {

@IBOutlet weak var headerLabel: UILabel!

// MARK: - View methods
override func prepareForInterfaceBuilder() {
    self.awakeFromNib()
}

override public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    //check that there are no current subviews
    if self.subviews.count == 0 {
        self.setupNib()
    }
}


// MARK: - NSCoding
required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    //check that there are no current subviews
    if self.subviews.count == 0 {
        self.setupNib()
    }
}


override func awakeFromNib() {
    super.awakeFromNib()

    self.backgroundColor = UIColor.blue
    if headerLabel != nil {
        self.headerLabel.text = "Hello world"
    }
}

func setupNib(){
    let bundle = Bundle(for: CustomTableView.self)
    guard let customView = bundle.loadNibNamed("CustomTableView",owner: self, options: nil)?.first as? CustomTableView else {
        return
    }
    customView.frame = self.bounds
    self.addSubview(customView)
 }
}

Спасибо!


person PAK    schedule 27.03.2017    source источник
comment
Пожалуйста, добавьте методы источника данных tbaleView.   -  person CodeChanger    schedule 27.03.2017
comment
Добавлены методы источника данных. Я пытаюсь установить метку внутри моего проектируемого UITableViewCell, что означает, что я получил IBOutlet для своей метки? Разве он не должен быть инициализирован тогда?   -  person PAK    schedule 27.03.2017
comment
Можете ли вы опубликовать код для большего пояснения?   -  person CodeChanger    schedule 27.03.2017
comment
Да, я отредактировал свой вопрос. Файл xib обновляет цвет фона, но когда я пытаюсь обновить текст headerLabel, происходит сбой построителя IB   -  person PAK    schedule 27.03.2017


Ответы (1)


Я думаю, что есть несколько возможных проблем, которые вы можете рассмотреть здесь. Во-первых, всякий раз, когда вы создаете собственное представление, вам нужно будет связать его с именем файла xib.

func setupNib(){
    let bundle = Bundle(for: ProgressHeaderTableViewCell.self)
    guard let customView = bundle.loadNibNamed("NAME_OF_XIB_FILE_GOES_HERE",owner: self, options: nil)?.first as? ProgressHeaderTableViewCell else {
         return 
    } 
    customView.frame = self.bounds
    self.addSubview(customView)
}

Кроме того, всякий раз, когда я работаю с файлами xib, я выполняю любую настройку представления в методе awakeFromNib() после проверки, чтобы убедиться, что один из ожидаемых элементов не равен нулю.

override func awakeFromNib() {
    if headerLabel != nil {
        self.backgroundColor = UIColor.blue
        self.headerLabel.text = "Hello world"
    }
}

Наконец, мне удалось заставить IBDesignables работать только тогда, когда я оборачиваю функции настройки проверкой отсутствия текущих подпредставлений:

override public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    //check that there are no current subviews 
    if self.subviews.count == 0 {
        self.setupNib()
    }
}

// MARK: - NSCoding
required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    //check that there are no current subviews 
    if self.subviews.count == 0 {
        self.setupNib()
    }
}

P.S. Когда я изучал это, я нашел этот пост в блоге очень полезным. Вы можете прочитать его самостоятельно, чтобы получить представление о IBDesignable и пользовательских представлениях. http://supereasyapps.com/blog/2014/12/15/create-an-ibdesignable-uiview-subclass-with-code-from-an-xib-file-in-xcode-6< /а>

person faircloud    schedule 27.03.2017
comment
Спасибо за ваш ответ! Я до сих пор не могу заставить свою пользовательскую ячейку работать в IB, но теперь она больше не падает. Текущий рабочий код обновлен в исходном сообщении ^^. Он только обновляет мое пользовательское представление в раскадровке, когда я использовал prepareForInterfaceBuilder(), как показано выше, где я могу установить синий цвет фона. Но в данный момент метка нулевая. - person PAK; 27.03.2017
comment
Не вызывайте пробуждение из ниба, этот метод будет вызван для вас. - person faircloud; 27.03.2017
comment
Если я удалю: переопределить func prepareForInterfaceBuilder() { self.awakeFromNib() } Ничего не отображается в IB - person PAK; 27.03.2017
comment
Вы реализовали метод init(frame: CGRect)? - person faircloud; 27.03.2017
comment
Хорошо, я думаю, что нашел проблему, почему она не была вызвана. Я удалил if self.subviews.count == 0 { self.setupNib() }. А потом он обновил мой IB. Спасибо за помощь! - person PAK; 27.03.2017