分隔线出现早于单元格标题并且图像超出 UIImageView
Posted
技术标签:
【中文标题】分隔线出现早于单元格标题并且图像超出 UIImageView【英文标题】:Separator line appear early than cell title and image goes beyond of UIImageView 【发布时间】:2020-07-07 11:47:23 【问题描述】:我以编程方式创建了 UITableView 和 Cell。一切正常,但我有几个关于约束和自动布局的问题:
layoutMarginsGuide 的约束:
-
在宽度为 375 的屏幕中,下部分隔符和单元格从一个点开始。在大尺寸屏幕上,分隔符出现在单元格标题之前(您可以在随附的屏幕截图中看到)。我该如何解决这个问题?
所附屏幕截图中红色圆角矩形的图像超出了 UIImageView。我向 UIImageView 添加了约束,但这对我没有帮助。我该如何解决这个问题?
没有 layoutMarginsGuide 的约束:
-
我希望 stackView 覆盖整个单元格。如何在不使用 layoutMarginsGuide 的情况下添加约束并避免控制台警告?
如何添加高度限制?我希望我的 stackView 或标题为 100 pt。
您可以在下面找到屏幕截图、单元格图标和代码。
感谢您的回答。
Rectangle with rounded corners
截图:
代码:
import Foundation
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
// MARK: - Lifecycle Methods
override func viewDidLoad()
super.viewDidLoad()
let tableViewstyle = UITableView.Style.insetGrouped
let tableView = UITableView(frame: CGRect(), style: tableViewstyle)
tableView.delegate = self
tableView.dataSource = self
tableView.register(Cell1.self, forCellReuseIdentifier: String(Cell1.description()))
tableView.tableFooterView = UIView()
tableView.translatesAutoresizingMaskIntoConstraints = false
self.view.backgroundColor = .systemBackground
self.view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.widthAnchor.constraint(equalTo: self.view.widthAnchor),
tableView.heightAnchor.constraint(equalTo: self.view.heightAnchor)
])
// MARK: - numberOfSections
func numberOfSections(in tableView: UITableView) -> Int
return 1
// MARK: - numberOfRowsInSection
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 7
// MARK: - cellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: String(Cell1.description())) as! Cell1
cell.title.text = "Cell \(indexPath.row)"
cell.icon2.image = UIImage(named: "Icon")
return cell
// MARK: - Cell
class Cell1: UITableViewCell
// MARK: - Properties
let title = UILabel()
let icon2 = UIImageView()
let stackView = UIStackView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Off translatesAutoresizingMaskIntoConstraints
title.translatesAutoresizingMaskIntoConstraints = false
icon2.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false
// Set constraints
icon2.addConstraint(NSLayoutConstraint(item: icon2, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 30))
icon2.addConstraint(NSLayoutConstraint(item: icon2, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 30))
// StackView
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fill
// TitleAndDetailStackView
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fill
// Hugging
title.setContentHuggingPriority(UILayoutPriority(rawValue: 750), for: .horizontal)
// Resistance
title.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 750), for: .horizontal)
icon2.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 250), for: .horizontal)
title.textAlignment = .left
title.numberOfLines = 0
// Highlight stackView and set colors
stackView.addBackground(color: .green)
title.textColor = .label
icon2.backgroundColor = .cyan
// Add title and detail
stackView.addArrangedSubview(title)
stackView.addArrangedSubview(icon2)
icon2.contentMode = .center
// Add to subview
self.contentView.addSubview(stackView)
// Get layoutMarginsGuide
let layoutMarginsGuide = contentView.layoutMarginsGuide
// Set constraints
NSLayoutConstraint.activate([
// Constrain all 4 sides of the stack view to the content view's layoutMarginsGuide
stackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: 0.0),
stackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: 0.0),
stackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor, constant: 0.0),
stackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor, constant: 0.0),
])
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
// MARK: - AddBackground
extension UIStackView
func addBackground(color: UIColor)
let subView = UIView(frame: bounds)
subView.backgroundColor = color
subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
insertSubview(subView, at: 0)
【问题讨论】:
【参考方案1】:为此,我们需要将约束更改为contentView.
,并将leadingAnchor.constraint
常量设置为等于16.0
。
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0.0),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0.0),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0.0),
])
将icon2.contentMode = .center
更改为icon2.contentMode = .scaleAspectFit
覆盖整个单元格的StackView:
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0.0),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0.0),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0.0),
])
要改变单元格的高度,我们可以简单地为单元格内的任何对象添加高度约束:
title.addConstraint(NSLayoutConstraint(item: title, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100))
【讨论】:
以上是关于分隔线出现早于单元格标题并且图像超出 UIImageView的主要内容,如果未能解决你的问题,请参考以下文章
滑动 UITableViewRowActions 时意外出现分隔线