webentwicklung-frage-antwort-db.com.de

Wie kann man UITableViewCellStyleSubtitle und dequeueReusableCell in Swift einstellen?

Ich möchte eine UITableView mit subtitle- Zellen, die dequeueReusableCellWithIdentifier verwenden.

Mein ursprünglicher Objective-C-Code war:

static NSString*    reuseIdentifier = @"Cell";
    UITableViewCell*    cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if(!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
    }

Nachdem ich die wenigen UITableView-Fragen hier bereits auf SO durchsucht hatte, dachte ich, es in Swift so zu schreiben:

    tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

Aber das lässt mich nicht sagen, ich möchte einen subtitle-Stil. Also habe ich es versucht:

var cell :UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")

Das gibt mir eine subtitle-Zelle, lässt mich aber nicht dequeueReusableCellWithIdentifier.

Ich habe etwas mehr recherchiert und dieses Video-Tutorial angeschaut, aber er erstellt eine separate subclass von UITableViewCell.

Irgendwelche Ideen? Vielen Dank.

37
user3127576

Beachten Sie, dass UITableView in der Funktion als optional definiert ist. Dies bedeutet, dass Ihre ursprüngliche Zelldeklaration nach der Option in der Eigenschaft suchen muss. Die zurückgegebene Zelle in der Warteschlange ist ebenfalls optional. Stellen Sie daher sicher, dass Sie eine optionale Umwandlung in UITableViewCell vornehmen. Danach können wir das Auspacken erzwingen, weil wir wissen, dass wir eine Zelle haben.

var cell:UITableViewCell? = 
tableView?.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell
if (cell == nil)
{
   cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, 
                reuseIdentifier: reuseIdentifier)
}
// At this point, we definitely have a cell -- either dequeued or newly created,
// so let's force unwrap the optional into a UITableViewCell
cell!.detailTextLabel.text = "some text"

return cell
63
memmons

Im Grunde das Gleiche wie andere Antworten, aber ich komme damit um, mit bösen Optionals (Sie können nil nicht aus -tableView:cellForRow:atIndexPath: in Swift zurückgeben), indem Sie eine berechnete Variable verwenden:

Swift 3

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell: UITableViewCell = {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell") else {
            // Never fails:
            return UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "UITableViewCell")
        }
        return cell
    }()

    // (cell is non-optional; no need to use ?. or !)

    // Configure your cell:
    cell.textLabel?.text       = "Key"
    cell.detailTextLabel?.text = "Value"

    return cell
}

Bearbeiten:

Eigentlich wäre es besser, die Zelle stattdessen mit tableView.dequeueReusableCell(withIdentifier:for:) zu entschlüsseln. 

Diese spätere Variante der Funktion instanziiert automatisch eine neue Zelle, wenn keine zur Wiederverwendung verfügbar ist (genau wie mein Code explizit oben), und daher nevernil zurückgibt.

19
Nicolas Miari

Wenn Sie die Optionalität lieber vermeiden möchten, können Sie eine Unterklasse von UITableViewCell erstellen, die etwa folgendermaßen aussieht:

class SubtitleTableViewCell: UITableViewCell {

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Dann registrieren Sie es mit:

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
}

Dadurch kann der Code für die Zellanpassung wirklich schön sein:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)

    cell.textLabel?.text = "foo"
    cell.detailTextLabel?.text = "bar"

    return cell
}
13
Jeremy Massel

Bauen Sie einfach auf Memmons Antwort auf, indem Sie den Swift 2-Stil aufräumen ...

let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) ?? UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)

cell.detailTextLabel?.text = "some text"

return cell

Swift 3:

let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)

cell.detailTextLabel?.text = ""

return cell
10
jonlambert
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let reuseIdentifier = "cell"
    var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as UITableViewCell?
    if (cell == nil) {
        cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
    }
    cell!.textLabel?.text = self.items[indexPath.row]
    cell!.detailTextLabel?.text = self.items[indexPath.row]
    return cell!
}
5
Geoffrey

Da tableView.dequeueReusableCell(withIdentifier:, for:) eine nicht-null-Zelle zurückgibt, ist die if cell == nil-Prüfung immer false .. __ Ich habe jedoch eine Lösung gefunden, um die Standardstilzelle zu dem Stil (Wert1, Wert2 oder Untertitel) zu machen, den Sie möchten, da detailTextLabel der Standardstilzelle ist null, also überprüfe die Variable detailTextLabel, wenn sie gleich null ist, erstelle dann eine neue Stilzelle und gib sie der Zelle, wie zum Beispiel:

Swift 3:

var cell = tableView.dequeueReusableCell(withIdentifier: yourCellReuseIdentifier, for: indexPath)

if cell.detailTextLabel == nil {
    cell = UITableViewCell(style: .value1, reuseIdentifier: repeatCellReuseIdentifier)
}

cell.textLabel?.text = "Title"
cell.detailTextLabel?.text = "Detail"

return cell

Das funktioniert für mich.

Ich hoffe es hilft.

3
Meilbn

Sie können eine etwas andere Syntax als die von Memmons verwenden, um das erzwungene Auspacken zu verhindern:

let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell ?? UITableViewCell(style: .Subtitle, 
            reuseIdentifier: reuseIdentifier)

cell.detailTextLabel?.text = "some text"

return cell

Dies verwendet XCode 6.1 7, schnell 1.2 2.0-Syntax, wobei UITableView nicht mehr optional ist.

2
lammert

Wenn Sie nicht Ihre eigene benutzerdefinierte Zelle verwenden. Registrieren Sie einfach UITableViewCell mit Code. Dann können Sie Code bevorzugen.

Andernfalls wählen Sie das Storyboard aus, wählen Sie Ihre TableViewCell -> Gehe zu Attribut-Inspektor aus und wählen Sie den gewünschten Stil aus (siehe unten). 

 enter image description here

1
Sudhi 9135
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath:
 NSIndexPath) -> UITableViewCell {  
     var CellIdentifier:String = "Cell"  
     var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as? UITableViewCell  
     if cell == nil {  
        cell = UITableViewCell(style:UITableViewCellStyle(rawValue:3)!,reuseIdentifier:CellIdentifier)   
      }
    return cell!
}
0

Perfekt wie von Michael G. Emmons vorgeschlagen, jedoch in Xcode 6.1 verwendet 

if !cell { .....

Ich erhalte diesen Fehler:

Optionaler Typ '@ | value UITableViewCell?' kann nicht als boolean verwendet werden; teste stattdessen auf '! = nil'

Die akzeptierte Syntax lautet:

if cell == nil { ...
0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{

    var cell:UITableViewCell? =
        tableView.dequeueReusableCell(withIdentifier: "cell")
    if (cell != nil)
    {
        cell = UITableViewCell(style: UITableViewCellStyle.subtitle,
                               reuseIdentifier: "cell")
    }
    cell!.textLabel?.text = "ABC"
    cell!.detailTextLabel?.text = "XYZ"

    return cell!

  }
0
iOS Lifee