Eu estava tentando obter células tableView com texto com vários parágrafos. As strings atribuídas pareciam ser uma forma de obter espaço extra entre os parágrafos (algo um pouco mais bonito do que fazer duas alimentações de linha na string). Me deparei com este e outros posts quando descobri que as configurações de IB não se aplicavam no tempo de execução quando você queria colocar um texto diferente na célula.
A principal coisa que eu fiz foi adicionar uma extensão a String (usando Swift) para criar uma string atribuída com certas características. O exemplo aqui usa a fonte Marker Felt, pois é facilmente distinguível da Helvetica. O exemplo também mostra um pouco mais de espaçamento entre os parágrafos para torná-los mais distintos uns dos outros.
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
}
}
Então, em meu tableViewCell personalizado, você envia o texto que deseja e ele o converte em uma string atribuída no UILabel.
// MarkerFeltCell.swift
class MarkerFeltCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
func configureCellWithString(inputString : String) {
myLabel.attributedText = inputString.toMarkerFelt()
}}
No controlador de visualização com tableView, você deve registrar sua célula em viewDidLoad () - usei uma ponta, então algo como:
let cellName = "MarkerFeltCell"
tableView.registerNib(UINib(nibName: cellName, bundle: nil), forCellReuseIdentifier: cellName)
Para fazer com que a célula descubra a altura que deve ter, faça um protótipo de célula que é usado para obter informações de tamanho e nunca é adicionado ao tableView. Então, nas variáveis do seu controlador de visualização:
var prototypeSummaryCell : MarkerFeltCell? = nil
Então em (provavelmente substituir - dependendo do seu controlador de visualização) 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 { // ...
No código acima, o prototypeCell será preenchido na primeira vez que for necessário. O prototypeCell é então usado para descobrir a altura da célula após passar pelo processo de dimensionamento automático. Você precisará arredondar a altura com a função ceil (). Eu também adicionei algum fator de fudge extra.
O bit de código final é como você configura o texto para a célula. Para este exemplo, simplesmente:
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
}
}
Além disso, aqui está uma foto do bico. Fixou o rótulo nas bordas da célula (com a margem desejada), mas usou uma restrição "Maior que ou igual", com uma prioridade menor que "Obrigatório" para a restrição inferior.
Defina a fonte do rótulo como Atribuída. A fonte real do IB não importava.
O resultado neste caso: