AutoLayout: многострочная метка и кнопка фиксированного размера - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь скопировать следующий макет из приложения Kayak: kayak app

Макет состоит из UICollectionViewCell с UILabel и INUIAddVoiceShortcutButton .

Однако в моей реализации метка не заставляет ячейку растягиваться дальше, когда текст не помещается: Clipping text

Как можно заставить UICollectionViewCell расти с меткой, а не обрезать метку до размера ячейки?

Веськод для ячейки:

final class AddToSiriCell: CornerMaskCellBase {
  lazy var button: INUIAddVoiceShortcutButton = {
    let b = INUIAddVoiceShortcutButton(style: .whiteOutline)
    return b
  }()

  lazy var textLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    return label
  }()

  override init(frame: CGRect) {
    super.init(frame: frame)
    configureViews()
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  private func configureViews() {
    textLabel.text = "View balance with your pre-recorded Siri Command .View balance with your pre-recorded Siri Command  View balance with your pre-recorded Siri Command View balance with your pre-recorded Siri Command "
    contentView.backgroundColor = .white
    [button, textLabel].forEach(contentView.addSubview)
    button.snp.makeConstraints { (make) in
      make.top.bottom.trailing.equalTo(contentView.layoutMarginsGuide)
    }

    textLabel.snp.makeConstraints { (make) in
      make.top.bottom.leading.equalTo(contentView.layoutMarginsGuide).priority(.required)
      make.trailing.equalTo(button.snp.leading).priority(.required)
    }
  }
}

Обновление 1: добавлен «Базовый класс» с фиксированной шириной Вот базовый класс, который я использую для всех ячеек в UICollectionView:

import UIKit
import SnapKit

class AutoSizingCellBase: UICollectionViewCell {
  override class var requiresConstraintBasedLayout: Bool {
    return true
  }

  private final var widthConstraint: Constraint?

  override init(frame: CGRect) {
    super.init(frame: frame)
    contentView.layoutMargins = UIEdgeInsets(padding: 14)
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  override func updateConstraints() {
    if widthConstraint == nil {
      if let window = window {
        let width = window.bounds.width - 16
        contentView.snp.makeConstraints { (make) in
          widthConstraint = make.width.equalTo(width).priority(.required).constraint
        }
      }
      contentView.translatesAutoresizingMaskIntoConstraints = true
    }
    super.updateConstraints()
  }
}

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Установите верхние, нижние и левые ограничения метки с суперпредставлением, т.е. с представлением содержимого ячейкиТеперь присвойте кнопке фиксированные ограничения по высоте и ширине и укажите верхнее, левое и правое поля, левое поле должно быть с вашей меткой.Теперь установите свойство количества строк вашей метки равным нулю.Любые сомнения, пожалуйста, прокомментируйте.

0 голосов
/ 17 октября 2018

Установите верхнее ограничение на метке и кнопке на greaterThanOrEqual

Установите нижнее ограничение на метке и кнопке на lessThanOrEqual


Edit:

Оба должны также иметь ограничения centerY.

Вот полный пример (я не на iOS 12, поэтому я использовал стандартный UIButton вместо INUIAddVoiceShortcutButton).Я также установил фон метки на голубой, чтобы было легко увидеть его результирующий кадр:

//
//  SnapTableViewController.swift
//
//  Created by Don Mag on 10/19/18.
//

import UIKit

class SnapCell: UITableViewCell {

    lazy var theButton: UIButton = {
        let b = UIButton()
        b.backgroundColor = .yellow
        b.setTitle("Add to Siri", for: .normal)
        b.setTitleColor(.black, for: .normal)
        b.layer.cornerRadius = 8
        b.layer.borderColor = UIColor.black.cgColor
        b.layer.borderWidth = 1
        return b
    }()

    lazy var theLabel: UILabel = {
        let label = UILabel()
        label.numberOfLines = 0
        label.backgroundColor = .cyan
        return label
    }()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configureViews()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configureViews()
    }

    func configureViews() -> Void {

        contentView.backgroundColor = .white
        [theButton, theLabel].forEach(contentView.addSubview)

        // constrain button size to 120 x 40
        theButton.snp.makeConstraints { (make) in
            make.width.equalTo(120)
            make.height.equalTo(40)
        }

        // constrain button to trailing margin
        theButton.snp.makeConstraints { (make) in
            make.trailing.equalTo(contentView.layoutMarginsGuide)
        }

        // constrain button top to greaterThanOrEqualTo margin
        theButton.snp.makeConstraints { (make) in
            make.top.greaterThanOrEqualTo(contentView.layoutMarginsGuide)
        }

        // constrain button bottom to lessThanOrEqualTo margin
        theButton.snp.makeConstraints { (make) in
            make.bottom.lessThanOrEqualTo(contentView.layoutMarginsGuide)
        }

        // also constrain button to centerY
        theButton.snp.makeConstraints { (make) in
            make.centerY.equalTo(contentView.snp.centerY)
        }

        // constrain label to leading margin
        theLabel.snp.makeConstraints { (make) in
            make.leading.equalTo(contentView.layoutMarginsGuide)
        }

        // constrain label top to greaterThanOrEqualTo margin
        theLabel.snp.makeConstraints { (make) in
            make.top.greaterThanOrEqualTo(contentView.layoutMarginsGuide)
        }

        // constrain label bottom to lessThanOrEqualTo margin
        theLabel.snp.makeConstraints { (make) in
            make.bottom.lessThanOrEqualTo(contentView.layoutMarginsGuide)
        }

        // also constrain label to centerY
        theLabel.snp.makeConstraints { (make) in
            make.centerY.equalTo(contentView.snp.centerY)
        }

        // constrain label trailing to 8-pts from button leading
        theLabel.snp.makeConstraints { (make) in
            make.trailing.equalTo(theButton.snp.leading).offset(-8)
        }

    }

}

class SnapTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 100

    }

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SnapCell", for: indexPath) as! SnapCell

        switch indexPath.row % 4 {

        case 0:
            cell.theLabel.text = "One line label."

        case 1:
            cell.theLabel.text = "This label has\nTwo Lines."

        case 2:
            cell.theLabel.text = "This label has enough text that is will wrap to Three Lines (on an iPhone 7)."

        default:
            cell.theLabel.text = "View balance with your pre-recorded Siri Command .View balance with your pre-recorded Siri Command  View balance with your pre-recorded Siri Command View balance with your pre-recorded Siri Command "

        }

        return cell
    }

}

enter image description here

...