Использование автоматического макета в UITableviewCell

Я пытаюсь использовать автоматическое изменение размера ячеек UITableView в Swift с помощью snapKit! соответствующие флаги, установленные на UITableView, следующие:

self.rowHeight = UITableViewAutomaticDimension
self.estimatedRowHeight = 70.0

У меня есть UITextField, определенный в моем классе customUITableviewCell, например:

var uidTextField: UITextField = UITextField()

и первоначальная настройка текстового поля в моем пользовательском UITableViewCell выглядит так:

self.contentView.addSubview(uidTextField)
uidTextField.attributedPlaceholder = NSAttributedString(string: "Woo Hoo", attributes: [NSForegroundColorAttributeName:UIColor.lightGrayColor()])
uidTextField.textAlignment = NSTextAlignment.Left
uidTextField.font = UIFont.systemFontOfSize(19)
uidTextField.returnKeyType = UIReturnKeyType.Done
uidTextField.autocorrectionType = UITextAutocorrectionType.No
uidTextField.delegate = self
uidTextField.addTarget(self, action: "uidFieldChanged", forControlEvents: UIControlEvents.EditingChanged)
uidTextField.snp_makeConstraints { make in 
    make.left.equalTo(self.contentView).offset(10)
    make.right.equalTo(self.contentView)
    make.top.equalTo(self.contentView).offset(10)
    make.bottom.equalTo(self.contentView).offset(10)
}

когда я запускаю код, он отображается обрезанным и выдает ошибку в консоли, которая гласит:

Предупреждение только один раз: обнаружен случай, когда ограничения неоднозначно предлагают нулевую высоту для представления содержимого ячейки таблицы. Мы считаем обрушение непреднамеренным и вместо этого используем стандартную высоту.

Что-то не так с моими ограничениями autoLayout или это проблема с UIControls и авторазмером UITableView ячеек?


person CWineland    schedule 01.10.2015    source источник


Ответы (1)


В SnapKit (и Masonry) вы должны использовать отрицательные значения, чтобы добавить отступ справа или внизу представления. Вы используете offset(10) в своем ограничении bottom, что приводит к тому, что нижние 10 пунктов вашего текстового поля будут обрезаны.

Чтобы исправить это, вы должны задать нижнему ограничению отрицательное смещение:

uidTextField.snp_makeConstraints { make in 
    make.left.equalTo(self.contentView).offset(10)
    make.right.equalTo(self.contentView)
    make.top.equalTo(self.contentView).offset(10)
    make.bottom.equalTo(self.contentView).offset(-10)
}

Или вы можете получить те же ограничения, выполнив следующие действия:

uidTextField.snp_makeConstraints { make in 
    make.edges.equalTo(contentView).inset(UIEdgeInsetsMake(10, 10, 10, 0))
}

Когда вы используете способ inset(), вы должны использовать положительные значения для правой и нижней вставки.

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

EDIT: Это небольшой пример, который работает нормально (я жестко запрограммировал tableView с 3 пользовательскими ячейками, которые включают UITextField):

Контроллер представления:

import UIKit
import SnapKit

class ViewController: UIViewController {
    let tableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(tableView)
        tableView.dataSource = self
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 70
        tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "CustomCell")

        tableView.snp_makeConstraints { (make) -> Void in
            make.edges.equalTo(view)
        }
    }
}

extension ViewController: UITableViewDataSource {
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath)
        return cell
    }
}

CustomTableViewCell:

import UIKit

class CustomTableViewCell: UITableViewCell {
    let textField = UITextField()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        textField.attributedPlaceholder = NSAttributedString(string: "Woo Hoo", attributes: [NSForegroundColorAttributeName:UIColor.lightGrayColor()])
        textField.textAlignment = NSTextAlignment.Left
        textField.font = UIFont.systemFontOfSize(19)
        textField.returnKeyType = UIReturnKeyType.Done
        textField.autocorrectionType = UITextAutocorrectionType.No
        contentView.addSubview(textField)

        textField.snp_makeConstraints { (make) -> Void in
            make.edges.equalTo(contentView).inset(UIEdgeInsetsMake(10, 10, 10, 0))
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
person joern    schedule 03.10.2015
comment
Здравствуйте, извините, что я не ответил вам сегодня, однако ячейка по-прежнему имеет неправильный размер при использовании вставки, а не смещения, как вы предложили. Та же ошибка: обнаружен случай, когда ограничения неоднозначно предлагают нулевую высоту для представления содержимого ячейки таблицы. Мы считаем обрушение непреднамеренным и вместо этого используем стандартную высоту. Хотя я действительно считаю, что вы правы в неправильном использовании смещения. я все еще изучаю это - person CWineland; 05.10.2015
comment
Ваш UITextField имеет постоянную высоту? - person joern; 05.10.2015
comment
Это не так, я предполагал, что он будет иметь внутреннюю или заданную высоту, основанную на высоте текста. попробую задать высоту - person CWineland; 05.10.2015
comment
Я получаю сообщение о конфликте ограничений после указания высоты ‹SnapKit.LayoutConstraint:0x7fb9cad1de50@/Users/chris.wineland/Desktop/tableViewCellController.swift#55 UITextField:0x7fb9cad4c5f0.top == UITableViewCellContentView:0x7fb9cad4c9a0.top + 10.0›, ‹SnapKit›. LayoutConstraint:0x7fb9cad20370@/Users/chris.wineland/Desktop/tableViewCellController.swift#55 UITextField:0x7fb9cad4c5f0.bottom == UITableViewCellContentView:0x7fb9cad4c9a0.bottom — 10.0›, UITableViewCellContentView:0x7fb9cad4c9a0(44)]› - person CWineland; 05.10.2015
comment
Попробуйте переопределить системное ограничение высоты для contentView, задав ContentView ограничение высоты: make.height.equalTo(uidTextField) - person joern; 05.10.2015
comment
после установки высоты представления содержимого я получаю очень похожую ошибку, связанную с конфликтующими ограничениями. одна странная вещь, которую я замечаю, это то, что вызывается func sizeThatFits(size: CGSize) -> CGSize, у меня сложилось впечатление, что она не вызывается при использовании autolayout, есть функция, аналогичная функции для auotlayout - person CWineland; 05.10.2015
comment
Я попытался воспроизвести полученную вами ошибку, но все работает, как и ожидалось, без каких-либо ошибок. Пожалуйста, смотрите мой отредактированный ответ для кода, который я использовал. Может быть, вы делаете что-то по-другому? - person joern; 05.10.2015