Я пытаюсь создать пользовательский заголовок раздела для табличного представления, содержащего textView. Я создал простое приложение, адаптируясь из учебника. Это создает рабочий пример. Однако, когда я перемещаю код в мое производственное приложение, он не размещается правильно. Простое учебное приложение создает макет из nib (без Main.storyboard), а производственное приложение - нет. Я предполагаю, что это является частью проблемы. В обоих я использую .layoutMarginsGuide.
Код следует из дизайна пользовательского заголовка.
class TextViewHeader: UITableViewHeaderFooterView {
static let reuseIdentifer = "TextViewHeaderReuseIdentifier"
let sectionTextView = UITextView.init()
override public init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
sectionTextView.font = UIFont.preferredFont(forTextStyle: .title2)
sectionTextView.textColor = UIColor.blue
sectionTextView.backgroundColor = UIColor.yellow
sectionTextView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(sectionTextView)
let margins = contentView.layoutMarginsGuide
sectionTextView.isScrollEnabled = false
//sectionTextView.text = "Something"
sectionTextView.frameLayoutGuide.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
sectionTextView.frameLayoutGuide.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
sectionTextView.frameLayoutGuide.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
sectionTextView.frameLayoutGuide.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Обратите внимание, что макет определяется:
let margins = contentView.layoutMarginsGuide
И для простоты отслеживания размеров и размещения TextView я установил желтый фон.
sectionTextView.backgroundColor = UIColor.yellow
Требуется дополнительное программирование для регистрации заголовка в viewDidLoad, что я и сделал:
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.tableView.frame = self.view.bounds
self.tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.register(TextViewHeader.self, forHeaderFooterViewReuseIdentifier: TextViewHeader.reuseIdentifer)
self.view.addSubview(self.tableView)
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 300
}
И заменить:
tableView(_ tableView:, titleForHeaderInSection section:).
со следующим:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: TextViewHeader.reuseIdentifer) as? TextViewHeader else {
return nil
}
header.customTextView.text = "Section \(section + 1)"
return header
}
Это работает и вставляет textView с макетом, как и ожидалось.
![enter image description here](https://i.stack.imgur.com/DuRcY.png)
Однако, похоже, этого не происходит при переносе программирования в мое производственное приложение. В этом случае я объединяю этот программный макет с макетом в конструкторе интерфейса xcode. Что-то мешает макету.
В производственном приложении я использую подобный код в пользовательском дизайне заголовка. (включено ниже для полноты)
class TextViewHeader: UITableViewHeaderFooterView {
static let reuseIdentifer = "TextViewHeaderReuseIdentifier"
let sectionTextView = UITextView.init()
override public init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
sectionTextView.font = UIFont.preferredFont(forTextStyle: .title2)
sectionTextView.textColor = UIColor.blue
sectionTextView.backgroundColor = UIColor.yellow
sectionTextView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(sectionTextView)
let margins = contentView.layoutMarginsGuide
sectionTextView.isScrollEnabled = false
//sectionTextView.text = "Something"
sectionTextView.frameLayoutGuide.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
sectionTextView.frameLayoutGuide.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
sectionTextView.frameLayoutGuide.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
sectionTextView.frameLayoutGuide.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Это дает следующий макет.
![enter image description here](https://i.stack.imgur.com/5Tdeg.png)
Просмотр раздела tableView моей раскадровки. Я вижу настройку «Высота заголовка раздела», которая установлена в автоматический режим, а «Оценка высоты строки» установлена в ноль. Изменение этой сметы для автоматизации приводит к изменению результатов:
Настройки:
![enter image description here](https://i.stack.imgur.com/CDTEm.png)
И полученный заголовок выглядит так:
![improved result](https://i.stack.imgur.com/7dFRD.png)
Лучше, но пространство над textView слишком велико.
Пытаясь исследовать, я вижу следующее после перерыва.
![the margins](https://i.stack.imgur.com/P9WE9.png)
Происхождение полей -8, -8 меня смущает. Более того, именно это я и получаю из своего примера, который отлично работает.
Однако при расследовании на этом перерыве я получаю следующие предупреждения:
2018-11-14 15: 21: 54.086637-0500 appName [31946: 1780119] [LayoutConstraints] Невозможно одновременно удовлетворить ограничения.
Вероятно, по крайней мере одно из ограничений в следующем списке
ты не хочешь Попробуйте это: (1) посмотреть на каждое ограничение и попытаться
выяснить, чего вы не ожидаете; (2) найти код, который добавил
нежелательное ограничение или ограничения и исправление.
Далее следует список нескольких ограничений, касающихся , ведущих и , трейлинг , но не top и bottom . Поэтому нет четких указаний на то, что нужно исправить.
Вот перечисленные ограничения
"<NSLayoutConstraint:0x600002364280 UILayoutGuide:0x6000039257a0'UIScrollView-frameLayoutGuide'.leading == UILayoutGuide:0x60000397a060'UIViewLayoutMarginsGuide'.leading (active)>",
"<NSLayoutConstraint:0x6000023642d0 UILayoutGuide:0x6000039257a0'UIScrollView-frameLayoutGuide'.trailing == UILayoutGuide:0x60000397a060'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x60000231b840 'UIView-Encapsulated-Layout-Width' _UITableViewHeaderFooterContentView:0x7fe43a815410.width == 0 (active)>",
"<NSLayoutConstraint:0x60000231b4d0 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x60000397a060'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UITableViewHeaderFooterContentView:0x7fe43a815410 )>",
"<NSLayoutConstraint:0x60000231b570 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x60000397a060'UIViewLayoutMarginsGuide']-(8)-|(LTR) (active, names: '|':_UITableViewHeaderFooterContentView:0x7fe43a815410 )>"
Моя единственная мысль - это смешивание "leftMargin" и "rightMargin" и ".leading" и ".trailing". Возможно ли в этом проблема? Но, как уже говорилось, проблема заключается в выравнивании сверху и снизу.
Мой обзор настроек раскадровки для tableView и заголовков tableView не дает никакой дополнительной информации о возможных конфликтах.
Чего мне не хватает?