2017-01-19 1 views
7

У меня есть UITableView с ячейками, которые содержат UILabel. UILabel имеет пользовательский интерфейс UIEdgeInset. Я подклассы в UILabel и установить UIEdgeInsets как это:UILabel с пользовательскими UIEdgeInsets, усекающимися в UITableViewCell

override func drawText(in rect: CGRect) { 
    super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) 
} 

override var intrinsicContentSize: CGSize { 
    var contentSize = super.intrinsicContentSize 
    contentSize.width += leftInset + rightInset 
    contentSize.height += topInset + bottomInset 
    return contentSize 
} 

Но метка получает усечен иногда, когда у меня есть несколько строк в UILabel. Я уже настроил высоту строки до UITableViewAutomaticDimension и установил значение RowHeight. Также ограничения прекрасны. Проблема заключается в том, что я устанавливаю UIEdgeInsets, так как он отлично работает, если я не настраиваю его.

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

Ограничения, добавленные в раскадровку. Bottom, Top, Leading и Trailing связаны с надписью (UITableViewCell). Все константы устанавливается в 0.

В cellForRowAtIndexPath код выглядит следующим образом:

let cell = tableView.dequeueReusableCell(withIdentifier: "AnswersCell", for: indexPath) as! AnswerCell 
cell.answerLabel.text = alternatives[indexPath.row] 
return cell 
+0

Лукаса вы, что метка только получает усечена, когда у вас есть более одной строки в метке? Посредством усечения я предполагаю, что вы имеете в виду разрезание по горизонтали делителем ячейки - то есть ячейка не будет правильно расширяться, чтобы разместить дополнительную строку в метке. Это верно? –

+0

Ваш подкласс подкласса ведет себя правильно для меня с помощью ячеек таблицы размеров, чтобы вы могли использовать код, который вы используете для настройки ячеек таблицы и подсмотров. – jamesk

+0

@ thecloud_of_unknowing yes, строка не подходит для представления. Это происходит не всегда, когда у меня есть несколько строк. Похоже, что он не рассматривает новые UIEdgeInsets, которые я установил. Таким образом, в некоторых случаях он подходит отлично, но другой может быть усечен, поскольку он ожидает, что останется больше пространства ширины. –

ответ

-1

Я подклассы мой ярлык, как это:

class PaddingLabel: UILabel { 

    var topInset: CGFloat = 0 
    var bottomInset: CGFloat = 0 
    var leftInset: CGFloat = 0 
    var rightInset: CGFloat = 0 

    override func drawText(in rect: CGRect) { 
     let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) 
     super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) 
    } 

    override var intrinsicContentSize: CGSize { 
     get { 
      var contentSize = super.intrinsicContentSize 
      contentSize.height += topInset + bottomInset 
      contentSize.width += leftInset + rightInset 
      return contentSize 
     } 
    } 
} 

Может быть, это get, что не хватает.

+0

На самом деле это не так. Когда у вас есть рассчитанное для чтения свойство, вы можете упростить его, удалив ключевое слово 'get' и его фигурные скобки. –

+0

Ну, этот ярлык отлично работает для меня. Все, что мне нужно сделать, это установить переменные (верхняя, нижняя, левая и правая вставки), и хорошо идти – Quaggie

1

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

Файл заголовка для UILabel предоставляет следующие комментарии для preferredMaxLayoutWidth:

// Если не равно нулю, это используется при определении -intrinsicContentSize для многострочных этикеток

В вашем случае, желаемое значение для preferredMaxLayoutWidth - это автоматическая ширина макета метки (то есть ширина ячейки таблицы), без каких-либо левых и правых вложений содержимого. Самый практичный способ установить это свойство в подклассе ячейки таблицы, потому что это наиболее простое место для доступа к ширине ячейки представления таблицы во время автоматического макета.

При выполнении автоматической компоновки для ячеек таблицы отображения размера, UITableView вызывает systemLayoutSizeFitting(_:withHorizontalFittingPriority:verticalFittingPriority) на каждую ячейку. (См. WWDC 2014 Session 226.) Размер фитинга, переданный этому методу, - это ширина представления таблицы с нулевой высотой, а приоритет горизонтальной установки - UILayoutPriorityRequired.

Таким образом, переопределить этот метод и установите желаемое значение для preferredMaxLayoutWidth:

// AnswerCell.swift 

@IBOutlet weak var answerLabel: AnswerLabel! 

override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize { 
    answerLabel.preferredMaxLayoutWidth = targetSize.width - answerLabel.insets.left - answerLabel.insets.right 
    return super.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: horizontalFittingPriority, verticalFittingPriority: verticalFittingPriority) 
} 

Эффекта является то, что при вычислении его высоты во время автоматической компоновки, UILabel использует значение preferredMaxLayoutWidth, которая была скорректирована для содержания которые обеспечивают, чтобы UITableView получал правильные высоты для своих ячеек.

Добавление

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

+0

Ваш (1) - это фигня, когда рисунок горизонтально вставляет текст, тогда 'intrinsicContentSize' должен учитывать это оставляя достаточно места. (2) находится на точке, хотя. –

+0

@ChristianSchnorr Значение 'intrinsicContentSize' не используется при рисовании текста. Горизонтальное пространство зарезервировано путем вставки прямоугольника, переданного в 'drawText (in:)'. Хотя 'intrinsicContentSize' не отвечал за проблему OP, он все еще был неправильным - он возвращал ширину, превышающую ширину супер-представления метки. Будьте гражданскими, пожалуйста. – jamesk

+0

'intrinsicContentSize' определяет размер выравнивания вида, т. Е. Если' alignmentRectInsets' не равен нулю, размер границ представления. Когда представление вставляет свои границы перед рисованием, для этого необходимо учитывать 'intrinsicContentSize'. –

1

Установите эти два свойства UILable из атрибутов инспектор секции раскадровки

  1. линий в 0
  2. Обрыв цепи к слову обернуть

или вы также можете установить эти свойства из кода.

self.answerLabel.numberOfLines = 0 
self.answerLabel.lineBreakMode = .byWordWrapping 

и поставить ниже код в подклассе вашего UILable в

class CustomLabel: UILabel { 

@IBInspectable var topInset: CGFloat = 5.0 
@IBInspectable var bottomInset: CGFloat = 5.0 
@IBInspectable var leftInset: CGFloat = 20.0 
@IBInspectable var rightInset: CGFloat = 5.0 

override func drawText(in rect: CGRect) { 
    let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset) 
    super.drawText(in: UIEdgeInsetsInsetRect(rect, insets)) 
} 

override var intrinsicContentSize: CGSize { 
    get { 
     var contentSize = super.intrinsicContentSize 
     contentSize.height += topInset + bottomInset 
     contentSize.width += leftInset + rightInset 
     return contentSize 
    } 
} 

}

попробовать это.

Надеется, что это будет работать для вас ..

+0

Чтобы 'intrinsicContentSize' был полезен для ярлыков, вам нужно сообщить им, где вы хотите их разбить:' preferredMaxLayoutWidth' –

Смежные вопросы