ios - 如何在 UITableView 中将 SF 符号相互对齐?
问题描述
在 WWDC SF Symbols 视频中,Apple 表示在显示 SF Symbols 时更喜欢水平和垂直对齐。据推测,这意味着每个都UIImageView.center.x
应该包含相同的值,以便它们排成一列。我的问题是如何确定 x 值应该是什么,因为它们都是不同的宽度。这是一个示例屏幕截图:
此屏幕截图使用UITableViewCellStyleDefault
withcell.imageView
和cell.textLabel
。但是,我想知道如何使用自定义实现相同的效果UITableViewCell
。只是根据 确定一定数量的宽度的正确方法UIImageSymbolConfiguration.pointSize
吗?一旦你有了那个宽度,所有的符号都将根据那个中心显示?
任何关于如何布局/对齐 SF 符号的指导,尤其是在不使用自动布局的情况下,都会非常有帮助:)
解决方案
这是一个非常简单的例子。
它循环遍历数据以确定将用于设置 imageView 的宽度约束常量的最宽符号。
class MySymbolCell: UITableViewCell {
let symbolImageView: UIImageView = {
let v = UIImageView()
v.contentMode = .center
return v
}()
let theLabel: UILabel = {
let v = UILabel()
return v
}()
var imageWidthConstraint: NSLayoutConstraint!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
symbolImageView.translatesAutoresizingMaskIntoConstraints = false
theLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(symbolImageView)
contentView.addSubview(theLabel)
// this way we can change imageView width at run-time if needed
imageWidthConstraint = symbolImageView.widthAnchor.constraint(equalToConstant: 40.0)
imageWidthConstraint.priority = UILayoutPriority(rawValue: 999)
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
// constrain imageView top / bottom / leading
symbolImageView.topAnchor.constraint(equalTo: g.topAnchor),
symbolImageView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
symbolImageView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
// constrain width
imageWidthConstraint,
// constrain height equal to width
symbolImageView.heightAnchor.constraint(equalTo: symbolImageView.widthAnchor),
// constrain label leading 8-pts from image view
theLabel.leadingAnchor.constraint(equalTo: symbolImageView.trailingAnchor, constant: 8.0),
// constrain label centerY to image view centerY
theLabel.centerYAnchor.constraint(equalTo: symbolImageView.centerYAnchor),
// constrain label trailing to content view trailing
theLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor),
])
}
}
class MySymbolTableViewController: UITableViewController {
var myData: [String] = [
"arrow.up",
"arrow.down",
"person.badge.plus",
"eye.slash",
"line.horizontal.3",
"textformat.123",
]
var symbolImageViewWidth: CGFloat = 40.0
// configure as desired
let imageConfig = UIImage.SymbolConfiguration(pointSize: 20, weight: .light, scale: .default)
override func viewDidLoad() {
super.viewDidLoad()
// calculate how wide you need your cell's symbol image view to be
// either run a loop to get the widest symbol your data is using,
// or
// just make sure you can fit the widest of the symbols ("bold.italic.underline")
let testLoop = true
if testLoop {
var maxW: CGFloat = 0.0
myData.forEach {
if let img = UIImage(systemName: $0, withConfiguration: imageConfig) {
maxW = max(img.size.width, maxW)
}
}
symbolImageViewWidth = maxW
} else {
if let img = UIImage(systemName: "bold.italic.underline", withConfiguration: imageConfig) {
symbolImageViewWidth = img.size.width
}
}
tableView.register(MySymbolCell.self, forCellReuseIdentifier: "MySymbolCell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MySymbolCell", for: indexPath) as! MySymbolCell
let img = UIImage(systemName: myData[indexPath.row], withConfiguration: imageConfig)
cell.symbolImageView.image = img
cell.theLabel.text = myData[indexPath.row]
cell.imageWidthConstraint.constant = symbolImageViewWidth
return cell
}
}
结果:
推荐阅读
- android - 科尔多瓦 android vue avd 资源公共图像
- hyperledger - 在 Ubuntu 上安装 Indy-node 失败
- react-native - 如何使用 React Native / Expo CLI 可靠地检测网络状态
- html - 如何使样式为 inline-block 的链接的背景不会出现在其后续链接兄弟姐妹的后面?
- java - How to call postgresql function with more than one input and output parameter from Java?
- flutter - 当子部件更改 Flutter 时更改父变量并重建父部件
- yocto - 覆盖 `DEFAULTTUNE` 和其他机器配置参数
- java - Spring boot RestHighLevelClient 弹性搜索组合查询
- java - Java:trustAnchors 参数必须为非空(openjdk)
- javascript - 在 JavaScript 按钮上应用某些 .class 并避免文本错位