Как правильно сделать свои ограничения с помощью UIImageView и нескольких меток в ячейке? - PullRequest
0 голосов
/ 08 июля 2019

В настоящее время я пытаюсь достичь функциональности динамических ячеек.Я фактически достиг этого, но используя только dateLabel, nameLabel и detailLabel.Я хочу включить изображение слева (authorProfileImg).Я пробовал несколько итераций и комбинаций ограничений для моих 4 элементов, но мне пока не удалось.Я пытался в течение 2 дней сейчас!Помощь будет высоко ценится, спасибо заранее!

class BookTableViewCell: UITableViewCell {

    let nameLabel = UILabel(frame: .zero)
    let detailLabel = UILabel(frame: .zero)

    let dateLabel = UILabel(frame: .zero)
    let authorProfileImg = UIImageView(frame: .zero)

    // MARK: Initalizers
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let marginGuide = contentView.layoutMarginsGuide

        // configure titleLabel //the upper element
        contentView.addSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false

        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor, constant: 60).isActive = true
        nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true

        nameLabel.numberOfLines = 0
        nameLabel.font = UIFont(name: "Arial", size: 16)

        // configure authorLabel //the lower element
        contentView.addSubview(detailLabel)
        detailLabel.translatesAutoresizingMaskIntoConstraints = false

        detailLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor, constant: 60).isActive = true
        //        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor, constant: -20).isActive = true
        detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 5).isActive = true

        detailLabel.numberOfLines = 0
        detailLabel.font = UIFont(name: "Arial", size: 13)
        detailLabel.textColor = UIColor.lightGray

        // configure dateLabel
        contentView.addSubview(dateLabel)
        dateLabel.translatesAutoresizingMaskIntoConstraints = false

        dateLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor, constant: 60).isActive = true
        dateLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        dateLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        dateLabel.topAnchor.constraint(equalTo: detailLabel.bottomAnchor, constant: 5).isActive = true

        dateLabel.numberOfLines = 0
        dateLabel.font = UIFont(name: "Arial", size: 12)
        dateLabel.textColor = UIColor.red
        dateLabel.text = "Jun 5"

        // configure author image
        contentView.addSubview(authorProfileImg)
        authorProfileImg.translatesAutoresizingMaskIntoConstraints = false

        authorProfileImg.widthAnchor.constraint(equalToConstant: 50).isActive = true
        authorProfileImg.heightAnchor.constraint(equalToConstant: 50).isActive = true
        authorProfileImg.layer.cornerRadius = 50

        authorProfileImg.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        authorProfileImg.topAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true

        authorProfileImg.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
//        authorProfileImg.trailingAnchor.constraint(equalTo: detailLabel.leadingAnchor).isActive = true
    }

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

}

Что я здесь не так делаю?

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

Вы были не слишком далеко.

Я считаю очень полезным группировать связанные строки кода - особенно при определении ограничений. Для меня гораздо проще отследить, что происходит.

Итак, в следующем коде я сгруппировал:

  • добавление подпредставлений
  • установка свойств элемента
  • определение ограничений

В комментариях вы увидите, что у меня есть одно ограничение для вертикального центрирования authorProfileImg и другое ограничение для его выравнивания сверху.

class BookTableViewCell: UITableViewCell {

    let nameLabel = UILabel(frame: .zero)
    let detailLabel = UILabel(frame: .zero)

    let dateLabel = UILabel(frame: .zero)
    let authorProfileImg = UIImageView(frame: .zero)

    // MARK: Initalizers
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let marginGuide = contentView.layoutMarginsGuide

        // add the subviews
        contentView.addSubview(nameLabel)
        contentView.addSubview(detailLabel)
        contentView.addSubview(dateLabel)
        contentView.addSubview(authorProfileImg)

        // we will use auto-layout constraints
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        detailLabel.translatesAutoresizingMaskIntoConstraints = false
        dateLabel.translatesAutoresizingMaskIntoConstraints = false
        authorProfileImg.translatesAutoresizingMaskIntoConstraints = false

        // configure labels and image view properties
        nameLabel.numberOfLines = 0
        nameLabel.font = UIFont(name: "Arial", size: 16)

        detailLabel.numberOfLines = 0
        detailLabel.font = UIFont(name: "Arial", size: 13)
        detailLabel.textColor = UIColor.lightGray

        dateLabel.numberOfLines = 0
        dateLabel.font = UIFont(name: "Arial", size: 12)
        dateLabel.textColor = UIColor.red
        dateLabel.text = "Jun 5"

        authorProfileImg.layer.cornerRadius = 25
        authorProfileImg.backgroundColor = .blue

        // set the constraints

        NSLayoutConstraint.activate([

            // image view leading is marginGuide leading
            authorProfileImg.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor, constant: 0.0),

            // image view centered vertically in cell
            authorProfileImg.centerYAnchor.constraint(equalTo: marginGuide.centerYAnchor, constant: 0.0),

            // if we want image view constrained to top of marginGuide (aligned to top of cell),
            // comment the above line (the centerYAnchor line) and un-comment this next line
            //authorProfileImg.topAnchor.constraint(equalTo: marginGuide.topAnchor, constant: 0.0),

            // image view is 50x50
            authorProfileImg.widthAnchor.constraint(equalToConstant: 50.0),
            authorProfileImg.heightAnchor.constraint(equalTo: authorProfileImg.widthAnchor),

            // name label constrained to top
            // leading is 10-pts from image view trailing
            // trailing is marginGuide trailing
            nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor, constant: 0.0),
            nameLabel.leadingAnchor.constraint(equalTo: authorProfileImg.trailingAnchor, constant: 10.0),
            nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor, constant: 0.0),

            // detail label top constrained 5-pts from bottom of name label
            // leading is equal to name label leading
            // trailing is marginGuide trailing -20 pts
            detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 5.0),
            detailLabel.leadingAnchor.constraint(equalTo: nameLabel.leadingAnchor, constant: 0.0),
            detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor, constant: -20.0),

            // date label top constrained 5-pts from bottom of detail label
            // leading is equal to name label leading
            // trailing is marginGuide trailing
            dateLabel.topAnchor.constraint(equalTo: detailLabel.bottomAnchor, constant: 5.0),
            dateLabel.leadingAnchor.constraint(equalTo: nameLabel.leadingAnchor, constant: 0.0),
            dateLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor, constant: 0.0),

            // date label bottom constrained to marginGuide bottom
            dateLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor, constant: 0.0),

            ])

    }

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

}

class BookTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(BookTableViewCell.self, forCellReuseIdentifier: "BookCell")

        // use a larger value if we expect rows to usually have multiple lines of text
        tableView.estimatedRowHeight = 60

    }

    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: "BookCell", for: indexPath) as! BookTableViewCell

        if indexPath.row % 2 == 0 {
            cell.nameLabel.text = "Row: \(indexPath.row) Name"
            cell.detailLabel.text = "Row: \(indexPath.row) Detail"
            cell.dateLabel.text = "Row: \(indexPath.row) Date"
        } else {
            cell.nameLabel.text = "Row: \(indexPath.row) Name with\nembedded new-line character."
            cell.detailLabel.text = "Row: \(indexPath.row) Detail label with enough text that it will need to word-wrap. Height of label will expand as needed."
            cell.dateLabel.text = "Row: \(indexPath.row) Date"
        }

        return cell

    }

}

И результаты (вертикально-центрированное изображение):

enter image description here

enter image description here

Выровненный по верху imageView:

enter image description here

0 голосов
/ 08 июля 2019

Это должно работать для вас:

   let marginGuide = contentView.layoutMarginsGuide

    // configure author image
    contentView.addSubview(authorProfileImg)
    authorProfileImg.translatesAutoresizingMaskIntoConstraints = false
    authorProfileImg.widthAnchor.constraint(equalToConstant: 50).isActive = true
    authorProfileImg.heightAnchor.constraint(equalToConstant: 50).isActive = true
    authorProfileImg.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
    authorProfileImg.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true

    // configure titleLabel //the upper element
    contentView.addSubview(nameLabel)
    nameLabel.translatesAutoresizingMaskIntoConstraints = false
    nameLabel.leadingAnchor.constraint(equalTo: authorProfileImg.trailingAnchor, constant: 10).isActive = true
    nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
    nameLabel.numberOfLines = 1
    nameLabel.font = UIFont(name: "Arial", size: 16)
    nameLabel.text = "name here"
    nameLabel.sizeToFit()

    // configure authorLabel //the lower element
    contentView.addSubview(detailLabel)
    detailLabel.translatesAutoresizingMaskIntoConstraints = false
    detailLabel.leadingAnchor.constraint(equalTo: nameLabel.leadingAnchor).isActive = true
    detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 5).isActive = true
    detailLabel.sizeToFit()

    detailLabel.numberOfLines = 1
    detailLabel.font = UIFont(name: "Arial", size: 13)
    detailLabel.textColor = UIColor.lightGray
    detailLabel.text = "detail here"

    // configure dateLabel
    contentView.addSubview(dateLabel)
    dateLabel.translatesAutoresizingMaskIntoConstraints = false
    dateLabel.leadingAnchor.constraint(equalTo: detailLabel.leadingAnchor).isActive = true
    dateLabel.topAnchor.constraint(equalTo: detailLabel.bottomAnchor, constant: 5).isActive = true
    dateLabel.sizeToFit()

    dateLabel.numberOfLines = 1
    dateLabel.font = UIFont(name: "Arial", size: 12)
    dateLabel.textColor = UIColor.red
    dateLabel.text = "Jun 5"

    self.sizeToFit()
...