Stavo cercando di ottenere celle tableView con testo con più paragrafi. Le stringhe attribuite sembravano essere un modo per ottenere spazio extra tra i paragrafi (qualcosa di un po 'più bello rispetto a due avanzamenti di riga nella stringa). Mi sono imbattuto in questo e in altri post quando ho scoperto che le impostazioni IB non si applicavano in fase di esecuzione quando si desiderava inserire un testo diverso nella cella.
La cosa principale che mi è venuta in mente è stata l'aggiunta di un'estensione a String (utilizzando Swift) per creare una stringa attribuita con determinate caratteristiche. L'esempio qui utilizza il carattere Marker Felt, poiché è facilmente distinguibile da Helvetica. L'esempio mostra anche un po 'più di spaziatura tra i paragrafi per renderli più distinti l'uno dall'altro.
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
}
}
Quindi, nel mio tableViewCell personalizzato, gli invii il testo che desideri e lo converte in una stringa attribuita su UILabel.
// MarkerFeltCell.swift
class MarkerFeltCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
func configureCellWithString(inputString : String) {
myLabel.attributedText = inputString.toMarkerFelt()
}}
Nel controller di visualizzazione con tableView, dovresti registrare la tua cella in viewDidLoad () - Ho usato un pennino, quindi qualcosa del tipo:
let cellName = "MarkerFeltCell"
tableView.registerNib(UINib(nibName: cellName, bundle: nil), forCellReuseIdentifier: cellName)
Per far capire alla cella quanto dovrebbe essere alta, crea un prototipo di cella che viene utilizzato per ottenere informazioni sulla dimensione e non viene mai aggiunto in tableView. Quindi, nelle variabili del controller di visualizzazione:
var prototypeSummaryCell : MarkerFeltCell? = nil
Quindi in (probabilmente sovrascrivere - a seconda del controller della vista) 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 { // ...
Nel codice precedente, prototypeCell verrà compilato la prima volta che è necessario. Il prototypeCell viene quindi utilizzato per calcolare l'altezza della cella dopo aver attraversato il processo di dimensionamento automatico. Dovrai arrotondare l'altezza con la funzione ceil (). Ho anche aggiunto qualche fattore di confusione extra.
Il bit di codice finale è il modo in cui configuri il testo per la cella. Per questo esempio, semplicemente:
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
}
}
Inoltre, ecco uno scatto del pennino. L'etichetta è stata fissata ai bordi della cella (con il margine desiderato), ma è stato utilizzato un vincolo "Maggiore di o uguale", con una priorità inferiore a "Obbligatorio" per il vincolo inferiore.
Imposta il carattere dell'etichetta su Attribuito. Il font IB effettivo non aveva importanza.
Il risultato in questo caso: