UILabel нельзя оборачивать и выравнивать одновременно - PullRequest
0 голосов
/ 07 января 2019

Я не могу одновременно обернуть и выровнять UILabel, отображаемое в UITableViewCell.

Я хочу, чтобы некоторые метки UILabels (отображались ниже на белом фоне) были выровнены по правому краю и слово переносится, если текст слишком длинный. Чтобы уточнить скриншоты ниже:

  • UILabel с белым фоном - метки, о которых я говорю
  • Я использую два разных типа ячеек (соответственно с синим и оранжевым фоном)
  • UITableView имеет что-то похожее на розовый фон
  • ViewController, в котором отображается UITableView, имеет светло-серый фон

Либо правильное выравнивание, но текст не обернут (На самом деле текст "Длинный .." длинный, см. Второй скриншот)

enter image description here

Или текст правильно обернут, но не выровнен по правому краю:

enter image description here

Мой код основан на этом руководстве: Как создать табличное представление с несколькими типами ячеек

Внутри кода для ячейки, отображаемой на оранжевом фоне:

class AttributeCell: UITableViewCell {

    @IBOutlet weak var titleLabel: UILabel?
    @IBOutlet weak var valueLabel: UILabel?
    let orange = UIColor(red: 1, green: 165/255, blue: 0, alpha: 1)

    var item: AttributeLabelLabel?  {
        didSet {
            titleLabel?.backgroundColor = .white
            titleLabel?.setLabel(contentText: (item?.attributeNameFromLocalizable)!, alignmentText: .right)

            valueLabel?.backgroundColor = .green
            valueLabel?.setLabel(contentText: (item?.attributeValue)!, alignmentText: .left)

            self.backgroundColor = orange
        }
    }

    static var nib:UINib {
        return UINib(nibName: identifier, bundle: nil)
    }

    static var identifier: String {
        return String(describing: self)
    }  
}

Я добавил расширение к UILabel, чтобы установить выравнивание и текст двух меток, отображаемых в ячейке, способ обтекания текста одинаков для всех меток.

С расширением ниже метка выровнена, но не обернута (см. Первый скриншот выше).

extension UILabel{
    func setLabel(contentText: String, alignmentText: NSTextAlignment){
        self.text = contentText
        self.textAlignment = alignmentText

        self.numberOfLines = 0
        self.lineBreakMode = .byWordWrapping     // inefficient alone
    }
}

Если я хочу, чтобы текст был обернут, я должен добавить вызов к sizeToFit(), но тогда короткая метка (см. Метку с текстом «Короткая») не выровнена по правому краю (см. Второй скриншот выше).

extension UILabel{
    func setLabel(contentText: String, alignmentText: NSTextAlignment){
        self.text = contentText
        self.textAlignment = alignmentText

        self.numberOfLines = 0
        self.lineBreakMode = .byWordWrapping
        self.sizeToFit()            // allow text to be effectivly wrapped
    }
}

Почему мне нужно указать self.sizeToFit() в документации, которую я нашел, упоминается только использование lineBreakMode для переноса текста?

Поскольку я не могу справиться с переносом слов и выравниванием текста, у меня возникла идея сравнить ширину UILabel с ее текстом, и в зависимости от сравнения обрабатывать выравнивание (для достаточно короткого текста) или перенос (если текст слишком длинный). Но я не нашел, как получить ширину UILabel.

Другой идеей было бы создать пользовательскую UILabel и установить все ограничения, сжатие и сопротивление в коде. На данный момент нет ограничений:

enter image description here

enter image description here Кто-то уже имел дело с такими проблемами?

Можно ли обрабатывать перенос текста и выравнивание текста одновременно?

Примечание:

На втором скриншоте UILabel с обернутым текстом перекрывает границы ячеек. Это не первая проблема, и я могу жить с этим сейчас, но если у кого-то есть подсказка об этом ... Я на самом деле использую следующий код для работы с ячейками разной высоты:

cell?.estimatedRowHeight = 200
cell?.rowHeight = UITableView.automaticDimension

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Вам не хватает нескольких ограничений.

Чтобы перенести многострочную метку, ее должна иметь ограниченную ширину (как иначе она узнает, что текст слишком длинный?).

Чтобы получить автоматическое расположение для настройки высоты ячейки, вам необходимо иметь ограничения на содержимое ячейки, чтобы «надавливать» на нижнюю часть ячейки.

Итак ...

  • Ограничьте ваш верхний левый ярлык Leading: 0, Top: 0, Width: 77 (в качестве ширины я использую 77, исходя из ваших изображений).
  • Ограничьте верхний правый ярлык до Leading: 8 (к последнему знаку верхнего левого ярлыка), Top: 0, Trailing: 0
  • Ограничьте левую нижнюю метку значением Leading: 0, Top: 8 (до нижней левой метки), Width: 77 (или шириной, равной верхней левой метке)
  • Ограничьте нижний правый ярлык до Leading: 8 (к концу нижнего левого ярлыка), Top: 8 (к нижнему правому краю ярлыка или Top: 0 к верху нижнего левого ярлыка), Trailing: 0

затем добавьте Bottom ограничения >= 0 к каждой из нижних меток.

Я предполагаю, что любая нижняя метка может переноситься на несколько строк, поэтому установите каждую на Number of Lines: 0

Макет:

enter image description here

результат:

enter image description here

0 голосов
/ 07 января 2019

A UILabel может быть выровнен по правому краю и перенесен на несколько строк. Вот пример:

enter image description here

На самом деле содержимое метки вводит в заблуждение, поскольку оно переносится на четыре строки! ; -)

Этого можно достичь с помощью ограничений AutoLayout и правильных настроек на UILabel. Этот конкретный UILabel ограничен следующим образом:

  • Вертикально по центру
  • Передний край для супер просмотра
  • Ширина

Вот ограничения, как показано в Интерфейсном Разработчике:

enter image description here

Наконец, чтобы иметь UILabel перенос строки на несколько строк, его свойство numberOfLines должно быть установлено равным 0, либо через Interface Builder, либо через код.

Вы также можете выровнять текст по правому краю, используя свойство textAlignment, установив его на .right, снова через Interface Builder или код.

...