Próbowałem uzyskać komórki tableView z tekstem zawierającym wiele akapitów. Przypisane ciągi wydawały się być sposobem na uzyskanie dodatkowej przestrzeni między akapitami (coś nieco ładniejszego niż zrobienie dwóch nowych linii w ciągu). Przeszedłem przez ten i inne posty, gdy odkryłem, że ustawienia IB nie mają zastosowania w czasie wykonywania, gdy chciałeś umieścić inny tekst w komórce.
Główną rzeczą, jaką wymyśliłem, było dodanie rozszerzenia do String (przy użyciu języka Swift), aby utworzyć przypisany ciąg o określonych cechach. W przykładzie użyto czcionki Marker Felt, ponieważ można ją łatwo odróżnić od czcionki Helvetica. Przykład pokazuje również trochę dodatkowych odstępów między akapitami, aby były one bardziej różne od siebie.
extension String {
func toMarkerFelt() -> NSAttributedString {
var style = NSMutableParagraphStyle()
style.paragraphSpacing = 5.0
let markerFontAttributes : [NSObject : AnyObject]? = [
NSFontAttributeName : UIFont(name: "Marker Felt", size: 14.0)!,
NSParagraphStyleAttributeName: style,
NSForegroundColorAttributeName : UIColor.blackColor()
]
let s = NSAttributedString(string: self, attributes: markerFontAttributes)
return s
}
}
Następnie w moim niestandardowym tableViewCell wysyłasz żądany tekst i konwertuje go na przypisany ciąg w UILabel.
// MarkerFeltCell.swift
class MarkerFeltCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
func configureCellWithString(inputString : String) {
myLabel.attributedText = inputString.toMarkerFelt()
}}
W kontrolerze widoku z tableView powinieneś zarejestrować swoją komórkę w viewDidLoad () - użyłem stalówki, czyli coś takiego:
let cellName = "MarkerFeltCell"
tableView.registerNib(UINib(nibName: cellName, bundle: nil), forCellReuseIdentifier: cellName)
Aby komórka obliczyła, jaka powinna być wysoka, utwórz prototypową komórkę, która jest używana do pobierania informacji o rozmiarze i nigdy nie jest dodawana do tableView. Tak więc w zmiennych kontrolera widoku:
var prototypeSummaryCell : MarkerFeltCell? = nil
Następnie w (prawdopodobnie przesłonięcie - w zależności od kontrolera widoku) heightForRowAtIndexPath:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// ...
if xib == "MarkerFeltCell" {
if prototypeCell == nil {
prototypeCell = tableView.dequeueReusableCellWithIdentifier(xib) as? MarkerFeltCell
}
let width : CGFloat = tableView.bounds.width
let height : CGFloat = prototypeCell!.bounds.height
prototypeCell?.bounds = CGRect(x: 0, y: 0, width: width, height: height)
configureCell(prototypeCell!, atIndexPath: indexPath)
prototypeSummaryCell?.layoutIfNeeded()
let size = prototypeSummaryCell!.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
let nextHeight : CGFloat = ceil(size.height + 1.0)
return nextHeight
} else { // ...
W powyższym kodzie prototypeCell zostanie wypełnione, gdy będzie to potrzebne po raz pierwszy. PrototypeCell jest następnie używany do obliczenia wysokości komórki po przejściu przez proces autodopasowania. Będziesz musiał zaokrąglić wysokość za pomocą funkcji ceil (). Dodałem też trochę dodatkowego krówki.
Ostatnim bitem kodu jest sposób konfiguracji tekstu komórki. W tym przykładzie po prostu:
func configureCell(cell :UITableViewCell, atIndexPath indexPath: NSIndexPath) {
if let realCell = cell as? MarkerFeltCell {
realCell.configureCellWithString("Multi-line string.\nLine 2.\nLine 3.") // Use \n to separate lines
}
}
Tutaj jest również ujęcie stalówki. Przypięto etykietę do krawędzi komórki (z wymaganym marginesem), ale zastosowano ograniczenie „Większe niż lub równe” z priorytetem mniejszym niż „Wymagany” dla ograniczenia dolnego.
Ustaw czcionkę etykiety na Attributed. Rzeczywista czcionka IB nie miała znaczenia.
Wynik w tym przypadku: