如何在UITableView中将SF符号彼此对齐?

问题描述 投票:2回答:1

在WWDC SF Symbols视频中,Apple说在显示SF Symbols时更喜欢水平和垂直对齐。据推测,这意味着每个UIImageView.center.x应该包含相同的值,以便它们在列中对齐。我的问题是如何确定x值应该是多少,因为它们都是不同的宽度。这是一个示例屏幕截图:

Screenshot

此屏幕快照使用UITableViewCellStyleDefaultcell.imageViewcell.textLabel。但是,我想知道如何使用自定义UITableViewCell实现相同的效果。基于UIImageSymbolConfiguration.pointSize来确定一定宽度的正确方法是正确的吗?确定宽度后,所有符号都会根据该中心显示吗?

关于如何布局/对齐SF符号的任何指导,特别是在不使用自动布局的情况下,都将非常有用:)

ios iphone uitableview uiimage sf-symbols
1个回答
0
投票

这是一个非常简单的示例。

它遍历数据以确定将用于设置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
    }

}

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.