Обходной путь отсутствия пользовательского метода init при использовании пользовательского UITableViewCell - PullRequest
0 голосов
/ 20 января 2019

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

Я пытался унаследовать от моего UITableViewCell класса и установить enum стиля в моем методе init, но я не могу установитьэто перед вызовом super.init.

class LabelIntegerTextfieldTableViewCell: LabelTextfieldTableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
    {
        super.textFieldStyle = .Integer
// 'self' used in property access 'textFieldStyle' before 'super.init' call

        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
open class LabelTextfieldTableViewCell: UITableViewCell
{
    public var label = UILabel()
    public var textField = UITextField()
    public var textFieldStyle = eTextfieldStyle.Integer

    override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        switch textFieldStyle
        {
        case .Integer:
            textField.contentVerticalAlignment = .center
            textField.textAlignment = .right
            textField.keyboardType = .numberPad
// snip

        if (textFieldStyle == .MediumText)
        {
            contentView.addConstraints(NSLayoutConstraint
              .constraints(withVisualFormat: 
              "H:|-[label]-[textField(==label)]-|", 
              options: [], metrics: nil, views: viewsDict))
        }
        else
        {
            contentView.addConstraints(NSLayoutConstraint
              .constraints(withVisualFormat: 
              "H:|-[label]-[textField(100)]-|", 
              options: [], metrics: nil, views: viewsDict))
        }

Я знаю, что в этом другом посте SO упоминается использование метода update, но, как я уже сказал, я бы предпочел не удалять ограничения и другие части.

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Поскольку ячейки используются повторно и вполне могут быть созданы с помощью dequeueReusableCell(reuseIdentifier:indexPath:), вы часто ничего не делаете в методах init.

В вашем случае я бы предложил вам создать функцию, которая настраивает вашу ячейку на основе свойства textFieldStyle (удаляя любую предыдущую конфигурацию, например, при необходимости ограничения; это может означать, что вам нужно сохранить ссылку на эти ограничения) в свойствах).

Вы можете вызвать эту функцию в двух местах:

  1. В awakeFromNib, если вы используете раскадровку) или init(style:reuseIdentifier:) if you aren't, to configure the cell according to the default value of textFieldStyle`
  2. В didSet наблюдателе от самого textFieldStyle.

, например

open class LabelTextfieldTableViewCell: UITableViewCell
{
    public var label = UILabel()
    public var textField = UITextField()
    public var textFieldStyle = eTextfieldStyle.Integer {
       didSet {
           self.configureCell()
       }
    }

    override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
{
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.configureCell()
    }

    override func awakeFromNib() {
         super.awakeFromNib()
         self.configureCell()
    }

    private func configureCell() {


        switch textFieldStyle {
        case .Integer:
            textField.contentVerticalAlignment = .center
            textField.textAlignment = .right
            textField.keyboardType = .numberPad
// snip

        if (textFieldStyle == .MediumText)
        {
            contentView.addConstraints(NSLayoutConstraint
          .constraints(withVisualFormat: 
          "H:|-[label]-[textField(==label)]-|", 
          options: [], metrics: nil, views: viewsDict))
        }
        else
        {
            contentView.addConstraints(NSLayoutConstraint
          .constraints(withVisualFormat: 
          "H:|-[label]-[textField(100)]-|", 
          options: [], metrics: nil, views: viewsDict))
        }

В вашем cellForRow(at:) вы просто удалили бы многократно используемую ячейку и установили ее тип:

    cell.textFieldStyle = .MediumText

Альтернативный подход - просто создать три разных подкласса и связать их с разными идентификаторами повторного использования. Затем вы можете настроить ячейку один раз в awakeFromNib / init

0 голосов
/ 20 января 2019

Поведение, которого вы пытаетесь достичь, на самом деле не очень хороший дизайн, потому что UITableViewCell s используются повторно. Поэтому не стоит полагаться на настройку их внешнего вида в методе init. Например, вы можете создать экземпляр ячейки, передающей стиль Integer, и позже, если вы установите для ячейки другой стиль, у вас будет несовместимое состояние (поскольку то, что вы увидите, не будет отражать то, что вы установили). При этом вы должны рассмотреть возможность использования более реактивного подхода, когда ваша ячейка ведет себя в соответствии с тем, что установлено, всякий раз, когда установлено. В вашем случае, возможно, вы захотите взглянуть на didSet свойства обозревателя. Вы бы что-то вроде ниже:

public var textFieldStyle = eTextfieldStyle.Integer {
  didSet {
    updateAppearance()
  }
}

func updateAppearance() {
  switch textFieldStyle {
    case .Integer:
      // ...
  }
}

EDIT

А в вашем tableView(_:cellForRowAt:) вам просто нужно установить правильный стиль следующим образом:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: "your cell identifier goes here", for: indexPath)

  // Here you obtain the proper style depending on the index path, for instance:
  if indexPath.row == 0 {
    cell.textFieldStyle = .Integer
  } else {
    cell.textFieldStyle = . MediumText
  }
  return cell
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...