Как задать динамическую высоту заголовка раздела представления коллекции - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть представление коллекции с заголовком раздела, который отображает информацию о пользователях.Заголовок может содержать биографию пользователя.У меня проблемы с изменением размера заголовка, если биография длинная.На этикетке не будет отображаться вся биография, поскольку заголовок остается на фиксированной высоте.

Я создал представление коллекции через раскадровку, однако я добавил ограничения программным способом.

Вот биологические ограничения, я думал, установив высоту и линии равными 0, все будет в порядке,

      addSubview(bioLabel)
        bioLabel.anchor(top: editProfileButton.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 12, paddingLeft: 12, paddingBottom: 0, paddingRight: 12, width: 0, height: 0)

Я также думал, что мог бы переопределить раскадровку на


    // Trying to override storyboard header height so the header can strech depending on the bio height
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

        //TODO change height to be bounds.height of bioLabel?
        return .init(width: view.frame.width, height: 300)

    }

, но, похоже, даже если я пытаюсь изменить размер с помощью кода, он сохраняет высоту раскадровки равной 225 (это то, что яхотел бы)

Ответы [ 5 ]

2 голосов
/ 19 сентября 2019

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

Экземпляры UICollectionReusableView имеют preferredLayoutAttributesFitting() метод.Когда ячейка станет отображаться, этот метод будет вызван.В этом методе, если вы используете Auto Layout, вы запрашиваете у всей ячейки systemLayoutSizeFitting(), а затем изменяете атрибуты.Макет будет ответственен за их применение посредством аннулирования макета.

0 голосов
/ 19 сентября 2019

Вы должны рассчитать размер высоты ячейки в методе

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

 var size = CGSize()
            let cell = YourUICollectionViewCell()
            cell.textLabel?.text = data?[indexPath.row].text
            let fitting = CGSize(width: cell.frame.size.width, height: 1)
            size = cell.contentView.systemLayoutSizeFitting(fitting,
                                                            withHorizontalFittingPriority: .required,
                                                            verticalFittingPriority: UILayoutPriority(1))
            return size.height //or just return size 

}

Если UILabel настроен на пользовательский режим, вам нужно установить нижнее ограничение UILabel для просмотра с приоритетом менее 1000.Надеюсь, это поможет

0 голосов
/ 19 сентября 2019

Эта функция сделает работу.Просто передайте текст метки

func estimatedLabelHeight(text: String) -> CGFloat {

        let size = CGSize(width: view.frame.width - 16, height: 1000)

        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)

        let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10)]

        let rectangleHeight = String(text).boundingRect(with: size, options: options, attributes: attributes, context: nil).height

        return rectangleHeight
    }

и используйте его как

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

        //TODO change height to be bounds.height of bioLabel?
        return .init(width: view.frame.width, height: estimatedLabelHeight(text: "Text that your label is gonna show"))

    }
0 голосов
/ 19 сентября 2019

Вы можете получить высоту этикетки, используя функцию ниже

func heightForLabel(text: String, font: UIFont, width: CGFloat) -> CGFloat {

  let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
  label.numberOfLines = 0
  label.lineBreakMode = NSLineBreakMode.byWordWrapping
  label.font = font
  label.text = text
  label.sizeToFit()

  return label.frame.height
}

Метод заголовка коллекции

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

    let height = self.heightForLabel(text: 'your text', font: 'font which you in label' , width: 'your label width')
    return .init(width: view.frame.width, height: height+10) //10 is extra height if you want or you can remove it.
}
0 голосов
/ 19 сентября 2019

Используйте экземпляр UICollectionReusableView в качестве вашего заголовка.И вычислите фактический размер заголовка в этом методе

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { }

Убедитесь, что ваш заголовок также готов к динамической высоте.Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...