2017-01-19 38 views
7

Mam UITableView z komórkami, które zawierają UILabel. Urządzenia UILabel mają niestandardowy zestaw narzędzi UIEdge. I podklasy z UILabel i ustawić UIEdgeInsets tak:UILabel z niestandardowym UIEdgeInsets obcięcie w 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 
} 

Ale etykieta zostanie obcięty czasami, kiedy mam więcej linii w UILabel. Skonfigurowałem już wysokość wiersza na UITableViewAutomaticDimension i ustawiono szacunkowoRowHeight. Również ograniczenia są w porządku. Problem wydaje się być, gdy ustawienie UIEdgeInsets, ponieważ działa poprawnie, jeśli nie dostosuję go.

Prawdopodobnie powinienem powiedzieć komórce, aby zaktualizować wiązania po ustawieniu wypustek, ale nie mogłem tego zrobić do tej pory.

Ograniczenia, które dodano w scenopisie. Bottom, Top, i Trailing są powiązane z widokiem (UITableViewCell). Wszystkie stałe ustawiona na 0.

W cellForRowAtIndexPath kod jest w następujący sposób:

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

Lucas mówisz etykieta zostanie obcięty tylko gdy masz więcej niż jedną linię na etykiecie? Po obcięciu przyjmuję, że masz na myśli odcięcie w poziomie przez dzielnik komórek - tzn. Komórka nie rozwija się prawidłowo, aby pomieścić dodatkową linię na etykiecie. Czy to jest poprawne? –

+0

Podklasa etykiet zachowuje się właściwie dla mnie z samokwającymi się komórkami widoku tabeli, więc możesz chcieć udostępnić kod, którego używasz do konfigurowania komórek i widoków tabeli. – jamesk

+0

@thecloud_of_unknowing Tak, ciąg nie pasuje do widoku. Nie zdarza się to przez cały czas, gdy mam więcej niż jedną linię. Wygląda na to, że nie bierze pod uwagę nowych ustawionych UIEdgeInsets. W niektórych przypadkach pasuje dobrze, ale inne mogą zostać obcięte, ponieważ spodziewają się większej przestrzeni. –

Odpowiedz

-1

I podklasy mojego Etykieta takiego:

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 
     } 
    } 
} 

Może to get że brakuje.

+0

Właściwie to nie to. Kiedy masz właściwość tylko do odczytu, możesz ją uprościć, usuwając słowo kluczowe "get" i jego nawiasy klamrowe. –

+0

Ta etykieta działa dobrze dla mnie. Wszystko, co muszę zrobić, to ustawić zmienne (górne, dolne, lewe, prawe wstawki) i dobrze jest przejść – Quaggie

1

Podczas automatycznego układania etykiety wielowierszowej, UILabel nie oblicza swojej wysokości za pomocą szerokości podanej w jego właściwości intrinsicContentSize, ale zamiast tego używa preferredMaxLayoutWidth, która nie została dostosowana w celu uwzględnienia wstawek treści.

Plik nagłówkowy dla UILabel zapewnia następujący komentarz do preferredMaxLayoutWidth:

// Jeśli niezerowe, to jest używany przy określaniu -intrinsicContentSize na multilinii etykiet

w przypadku, pożądana wartość dla preferredMaxLayoutWidth jest to szerokość automatycznego układu etykiety (tj. szerokość komórki widoku tabeli) pomniejszona o lewe i prawe wstawki zawartości. Najbardziej praktyczny sposób ustawienia tej właściwości znajduje się w podklasie komórek widoku tabeli, ponieważ jest to najbardziej proste miejsce dostępu do szerokości komórki widoku tabeli podczas automatycznego układu.

Podczas wykonywania automatycznego układu dla samokodujących komórki widoku tabeli, wywołania UITableView wywołują systemLayoutSizeFitting(_:withHorizontalFittingPriority:verticalFittingPriority) dla każdej komórki. (Patrz WWDC 2014 Session 226.) Wielkość dopasowania przekazywana do tej metody to szerokość widoku tabeli z zerową wysokością, a priorytetem dopasowania poziomego jest UILayoutPriorityRequired.

więc zastąpić tę metodę i ustawić żądaną wartość dla 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) 
} 

Efektem jest to, że przy obliczaniu jego wysokości podczas układ auto, UILabel wykorzystuje wartość preferredMaxLayoutWidth który został dostosowany do treści wstawek, które zapewniają, że UITableView otrzymuje poprawne wysokości dla swoich komórek.

Uzupełnienie

Alternatywnie, zamiast wszystkie powyższe, można po prostu zmienić ograniczenia na etykiecie do wstawka całą etykietę, albo bezpośrednio w widoku zawartości komórki widoku tabeli lub przez osadzenie go w innym podglądzie widoku treści.

+0

Twoja (1) jest bzdurą, kiedy rysunek poziomo wstawia tekst, wtedy "intrinsicContentSize" musi to wyjaśnić przez rezerwowanie wystarczającej ilości miejsca. (2) jest na punkcie jednak. –

+0

@ChristianSchnorr Wartość 'intrinsicContentSize' nie jest używana podczas rysowania tekstu. Przestrzeń pozioma jest zarezerwowana przez wstawienie rect przekazanego do 'drawText (in:)'. Chociaż 'intrinsicContentSize' nie był odpowiedzialny za problem związany z OP, był nadal niepoprawny - zwracał szerokość większą niż szerokość super widoku etykiety. Bądź uprzejmy, proszę. – jamesk

+0

'intrinsicContentSize' określa rozmiar wyrównania widoku, tj. O ile' alignmentRectInsets' nie jest równe zeru, rozmiar widoku widoku. Kiedy widok przed uruchomieniem wykasuje granice, to "intrinsicContentSize" musi to wyjaśnić. –

1

Ustaw te dwie właściwości UILable z sekcji Atrybuty inspektor z storyboard

  1. Lines do 0
  2. linię przerwania do słowa owinąć

lub można również ustawić te właściwości z kodem.

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

i umieścić poniżej kod w swoim UILable za podklasy

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 
    } 
} 

}

spróbować.

nadzieję, że będzie pracować dla Ciebie ..

+0

Aby opcja 'intrinsicContentSize' była użyteczna na etykietach, musisz powiedzieć im, gdzie mają się one dzielić:' preferredMaxLayoutWidth' –