我正在尝试为包含textView的表视图创建自定义节标题。我根据教程创建了一个简单的应用程序。这创建了一个有效的示例。但是,当我将代码移到生产应用程序时,它的布局不正确。简单的教程应用程序从笔尖创建布局(没有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。
但是,当我将程序移到生产应用程序时,似乎没有发生同样的事情。在这种情况下,我将该程序化布局与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")
}
}
这给出了以下布局。
查看故事板的tableView部分。我看到“节头高度”设置被设置为自动,“行高度的估计”设置为零。将估算值更改为自动即可更改结果:
结果标题如下所示:
更好,但textView上方的空间太大。
尝试调查后,我可以看到以下内容。
-8的边距起源,-8使我感到困惑。此外,这正是我从示例中获得的完美运行的结果。
但是,在调查此休息时,我收到以下警告:
2018-11-14 15:21:54.086637-0500 appName [31946:1780119] [LayoutConstraints]无法同时满足约束。 以下列表中的约束中至少有一个是 你不要试试这个:(1)查看每个约束并尝试 找出你不期望的东西; (2)找到添加了 不必要的约束或约束并进行修复。
此后列出了几个有关 lead 和 trailing 的约束,但没有列出 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标头的情节提要上的设置的回顾没有发现有关可能冲突的更多信息。
我可能会想念什么?
答案 0 :(得分:0)
我发现这是一个有问题的方法。目前,NSLayoutConstraint问题超出了我的Swift知识范围。它似乎是由事件发生的时间驱动的。此外,有一些讨论认为它有些错误。请参阅以下内容:What is NSLayoutConstraint "UIView-Encapsulated-Layout-Height" and how should I go about forcing it to recalculate cleanly?
我决定放弃使用tableView.dequeueReusableHeaderFooterView。分区的数量将受到限制(2到3个,大量使用),因此成本将降至最低。
因此,我实现了一个简单的方法。
//define size of font to use
let sectionFont = UIFont.preferredFont(forTextStyle: .title3)
let fontsize = UIFont.preferredFont(forTextStyle: .title3).pointSize
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: tableView.frame.width, height: fontsize+10))
let textView = UITextView()
textView.frame = CGRect.init(x: 0, y: -10, width: headerView.frame.width-10, height: headerView.frame.height-0)
textView.text = "Section \(section)"
textView.font = sectionFont
headerView.addSubview(textView)
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return fontsize+10
}