Как вы выравниваете символы SF друг с другом в UITableView? - PullRequest
2 голосов
/ 08 апреля 2020

В видео WWD C SF Symbols компания Apple предпочитает горизонтальное и вертикальное выравнивание при отображении SF-символов. Предположительно, это означает, что каждый UIImageView.center.x должен содержать одно и то же значение, чтобы они располагались в столбце. Мой вопрос заключается в том, как определить, что это значение х должно быть, поскольку они все разной ширины. Вот пример снимка экрана:

Screenshot

Этот снимок экрана использует UITableViewCellStyleDefault с cell.imageView и cell.textLabel. Тем не менее, я хочу знать, как добиться того же эффекта, используя пользовательский UITableViewCell. Является ли правильный способ просто определить определенное количество ширины на основе UIImageSymbolConfiguration.pointSize? Как только у вас будет эта ширина, все символы будут отображаться в соответствии с этим центром?

Любое руководство по компоновке / выравниванию символов SF, особенно без использования автоматического макета, было бы очень полезно:)

1 Ответ

1 голос
/ 10 апреля 2020

Вот очень простой пример.

Он проходит по данным, чтобы определить самый широкий символ, который будет использоваться для установки константы ограничения ширины 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

...