如何排列不同的 UITableViewCell 图像和标签?
Posted
技术标签:
【中文标题】如何排列不同的 UITableViewCell 图像和标签?【英文标题】:How can I line up different UITableViewCell images and labels? 【发布时间】:2019-07-28 19:46:50 【问题描述】:我在cellForRowAt
中所做的只是设置 UITableViewCell 的(无子类)imageView?.image 和 textLabel?.text 值(以及字体和颜色)。根据我的模型通过 SF Symbols 和文本设置图像。更详细地说,只有三种可能的单元格类型:工作区、“添加工作区”按钮和存档。
在下面的屏幕截图中,我用绿线演示了这些视图如何不完全按照逻辑方式排列。所有三种类型的单元格之间的文本都未对齐,并且(令人讨厌的)带有“添加”(+)指示符的方形图标的 SF 符号图像比标准图像略宽。
任何人都可以帮助我解决这个我只是想念的简单问题吗?我已经尝试使用约束将 imageViews 的纵横比设置为 1:1。这没有任何影响。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell: UITableViewCell
if indexPath.section == 0
cell = tableView.dequeueReusableCell(withIdentifier: "workspace", for: indexPath)
if indexPath.row == addWorkspaceRow
cell.imageView?.image = .addWorkspace
cell.imageView?.tintColor = cell.tintColor
cell.textLabel?.text = "Add Workspace"
cell.textLabel?.textColor = cell.tintColor
cell.accessoryType = .none
else
let workspace = model.workspaces[indexPath.row]
cell.imageView?.image = .workspace
cell.imageView?.tintColor = .label
cell.textLabel?.text = workspace.displayName
cell.textLabel?.textColor = .label
cell.accessoryType = .disclosureIndicator
else
cell = tableView.dequeueReusableCell(withIdentifier: "archive", for: indexPath)
cell.imageView?.image = .archive
cell.imageView?.tintColor = .archive
cell.textLabel?.text = "Archive"
cell.textLabel?.textColor = .label
cell.accessoryType = .disclosureIndicator
cell.textLabel?.font = .preferredFont(forTextStyle: .body)
return cell
【问题讨论】:
哥们,你只需要玩一些约束。将“添加”图像的约束设置为与默认(黑色)图像相同。 【参考方案1】:我遇到了同样的事情,想在不使用自定义单元格的情况下解决它。但是没有子类化约束是很难配置的。
最终,我转而使用自定义单元格,它使用简单,如果您可能需要在 tableView 单元格中添加更多内容,自定义单元格是更好的选择。
我的代码,是的,我现在正在制作音乐播放器;)
class LibraryTableCell: UITableViewCell
var cellImageView = UIImageView()
var cellLabel = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: "libraryTableCell")
cellImageView.translatesAutoresizingMaskIntoConstraints = false
cellImageView.contentMode = .scaleAspectFit
cellImageView.tintColor = .systemPink
contentView.addSubview(cellImageView)
cellLabel.translatesAutoresizingMaskIntoConstraints = false
cellLabel.font = UIFont.systemFont(ofSize: 20)
contentView.addSubview(cellLabel)
NSLayoutConstraint.activate([
cellImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
cellImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
cellImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20),
cellImageView.widthAnchor.constraint(equalToConstant: 44),
cellLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
cellLabel.leadingAnchor.constraint(equalTo: cellImageView.trailingAnchor, constant: 10),
])
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
class LibraryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
var tableView = UITableView()
let cellTitles = ["Playlists", "Artists", "Albums", "Songs", "Genres"]
let imageNames = ["music.note.list", "music.mic", "square.stack", "music.note", "guitars"]
override func viewDidLoad()
super.viewDidLoad()
view.backgroundColor = .white
title = "Library"
navigationController?.navigationBar.prefersLargeTitles = true
tableView.delegate = self
tableView.dataSource = self
tableView.register(LibraryTableCell.self, forCellReuseIdentifier: "libraryTableCell")
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.rowHeight = 48
view.addSubview(tableView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
tableView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20),
tableView.heightAnchor.constraint(equalTo: g.heightAnchor, multiplier: 0.6)
])
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return cellTitles.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
guard let cell = tableView.dequeueReusableCell(withIdentifier: "libraryTableCell", for: indexPath) as? LibraryTableCell else
fatalError("Unable to dequeue libraryTableCell")
cell.accessoryType = .disclosureIndicator
let imageName = imageNames[indexPath.row]
cell.cellImageView.image = UIImage(systemName: imageName)
let title = cellTitles[indexPath.row]
cell.cellLabel.text = title
return cell
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
cell.separatorInset = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 8)
【讨论】:
【参考方案2】:更改UIImageView
的contentMode
属性就可以了:
cell.imageView?.contentMode = .scaleAspectFit
这是因为图像本身的尺寸不正确。
【讨论】:
我真的试过了,它并没有改变任何东西。即使将 imageView 的水平拥抱优先级设置为高也不起作用。 看来您使用的是 UITableViewCell 的原生 imageView,您是否尝试过对其进行子类化并实现自己的 imageView 并使用约束固定其大小? 我确信这会奏效。如果可能的话,我只是在避免那些(诚然很少量的)工作。感觉基类应该是可能的。 老实说,我总是直接对 UITableViewCell 进行子类化,只是为了增加自定义,以防万一我需要它。【参考方案3】:您在 tableviewCell 中的图像是错误的 contentMode。这是由于标签布局错误的原因。
您可以选择解决该问题:
选项1:
打开文件XIB tableviewCell并改变UIImage的内容模式
选项 2:
您可以通过代码设置:
yourUImage.contentMode = .scaleAspectFit
【讨论】:
您似乎在另一个(相同)答案上跳过了一些 cmets。这不适用于本机 UITableViewCell 类。它仅在您出于某种原因进行子类化时才有效。【参考方案4】:我为您描述的问题寻找了很长时间的解决方案,但遗憾的是我没有找到任何解决方案。问题似乎是UITableViewCell
中的原生UIImageView
。基本上有两种解决方法:
A) 将您用作表格视图单元格图标的所有图像调整为特定宽度(例如 30 和高度 44)。绘制这个空间并将图标居中(同时保持原始大小)
B) 习惯 Apple 的“您可以使用我们预先构建的解决方案,但如果您想改变一点点,您必须自下而上重新构建所有内容”——哲学只需使用自定义单元格来完成您在应用程序中所做的一切。使用自定义单元格,您可以简单地将 imageView 宽度设置为某个值。
我想知道他们是如何在 ios 邮件应用中解决这个问题的。
【讨论】:
以上是关于如何排列不同的 UITableViewCell 图像和标签?的主要内容,如果未能解决你的问题,请参考以下文章
重新排序单元格时如何在 UITableViewcell 内容视图中添加图像?
当 UIStackView 更改其排列的子视图时,UITableViewCell 不会调整大小