UITableView w języku Swift

Staram się zrozumieć, co jest nie tak z tym fragmentem kodu. Obecnie działa to w Objective-C, ale w Swift to po prostu zawiesza się na pierwszej linii metody. Wyświetla komunikat o błędzie w dzienniku konsoli: Bad_Instruction.

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {
        var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell

        if (cell == nil) {
            cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
        }

        cell.textLabel.text = "TEXT"
        cell.detailTextLabel.text = "DETAIL TEXT"

        return cell
    }
Author: Brian Tompsett - 汤莱恩, 2014-06-03

17 answers

Zobacz też odpowiedź Matta która zawiera drugą połowę roztworu

Znajdźmy rozwiązanie bez tworzenia niestandardowych podklas lub nib

Prawdziwy problem polega na tym, że Swift rozróżnia obiekty, które mogą być puste (nil) i obiekty, które nie mogą być puste. Jeśli nie zarejestrujesz stalówki dla swojego identyfikatora, {[3] } może zwrócić nil.

Oznacza to, że musimy zadeklarować zmienną jako opcjonalną:

var cell : UITableViewCell?

I mamy do odlewania za pomocą as? Nie as

//variable type is inferred
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell

if cell == nil {
    cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}

// we know that cell is not empty now so we use ! to force unwrapping but you could also define cell as
// let cell = (tableView.dequeue... as? UITableViewCell) ?? UITableViewCell(style: ...)

cell!.textLabel.text = "Baking Soda"
cell!.detailTextLabel.text = "1/2 cup"

cell!.textLabel.text = "Hello World"

return cell
 81
Author: Sulthan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:22

Odpowiedź Sulthan jest mądra, ale prawdziwe rozwiązanie brzmi: [9]} nie dzwoń dequeueReusableCellWithIdentifier. To był twój błąd na początku.

Ta metoda jest całkowicie przestarzała i dziwię się, że nie została formalnie przestarzała; żaden system, który może pomieścić Swift (iOS 7 lub iOS 8), nie potrzebuje jej do jakiegokolwiek celu.

Zamiast tego wywołaj nowoczesną metodę, dequeueReusableCellWithIdentifier:forIndexPath:. Ma to tę zaletę, że nie są zaangażowane żadne opcje; jesteś gwarantowane że komórka będzie zwrócony. Wszystkie znaki zapytania i wykrzykniki odpadają, możesz użyć let zamiast var, ponieważ istnienie komórki jest gwarantowane, a żyjesz w wygodnym, nowoczesnym świecie.

Jeśli nie używasz storyboardu, musisz wcześniej zarejestrować tabelę dla tego identyfikatora, rejestrując klasę lub stalówkę. Konwencjonalnym miejscem do tego jest viewDidLoad, czyli tak wcześnie, jak w ogóle istnieje widok tabeli.

Oto przykład użycia niestandardowej komórki Klasa:

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.registerClass(MyCell.self, forCellReuseIdentifier: "Cell")
}

// ...

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath) as MyCell
    // no "if" - the cell is guaranteed to exist
    // ... do stuff to the cell here ...
    cell.textLabel.text = // ... whatever
    // ...
    return cell
}

Ale jeśli używasz storyboardu (co robi większość ludzi), nie musisz nawet rejestrować widoku tabeli w viewDidLoad! Po prostu wprowadź identyfikator komórki w storyboardzie i możesz wybrać dequeueReusableCellWithIdentifier:forIndexPath:.

 63
Author: matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 21:02:37

@ Sulthan ' s answer is spot on. Jedną z możliwych modyfikacji wygody byłoby oddanie komórki jako UITableViewCell!, zamiast UITableViewCell.

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as UITableViewCell!
    if !cell {
        cell = UITableViewCell(style:.Default, reuseIdentifier: "CELL")
    }
    // setup cell without force unwrapping it
    cell.textLabel.text = "Swift"
    return cell
}

Teraz możesz modyfikować zmienną komórki bez konieczności jej rozpakowywania za każdym razem. Należy zachować ostrożność podczas korzystania z niejawnie rozpakowanych opcji. Musisz mieć pewność, że wartość, do której uzyskujesz dostęp, ma wartość.

Aby uzyskać więcej informacji, zapoznaj się z sekcją" domyślnie rozpakowane Opcje " programowania Swift Język .

 18
Author: aselvia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-15 22:10:21

Spróbuj tego:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    cell.textLabel.text = "\(indexPath.row)"

    return cell
}

Zauważ, że powinieneś zarejestrować się UITableViewCell i ID podczas tworzenia instancji twojego UITableView:

tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
 8
Author: Oscar Swanros,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-03 18:55:05

Oto, co napisałem, aby go uruchomić...

Najpierw zarejestruj komórkę widoku tabeli w widoku tabeli

self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")

Następnie skonfiguruj cellForRowAtIndexPath

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {
    var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MyTableViewCell

    cell.textLabel.text = "Cell Text"
    cell.detailTextLabel.text = "Cell Detail Text in Value 1 Style"

    return cell
}

Następnie zdefiniowałem niestandardową podklasę komórek write na dole pliku (ponieważ jest teraz o wiele łatwiejszy)

class MyTableViewCell : UITableViewCell {

    init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
    }

}
 8
Author: DBoyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-04 03:38:41

Jest tu kilka odpowiedzi, ale myślę, że żadna z nich nie jest idealna, ponieważ po deklaracji kończysz z opcjonalnym UITableViewCell, który następnie potrzebuje cell!... w dowolnych deklaracjach. Myślę, że jest to lepsze podejście (mogę to potwierdzić na Xcode 6.1):

var cell:UITableViewCell

if let c = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell {
    cell = c
}
else {
    cell = UITableViewCell()
}
 4
Author: Chris Simpson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-27 06:12:11

Oto prosty sposób na zdefiniowanie komórki tabeli w swift 2:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let identifier = "cell"
    let cell = tableView.dequeueReusableCellWithIdentifier(identifier) ??
        UITableViewCell.init(style: UITableViewCellStyle.Default, reuseIdentifier: identifier)
    cell.textLabel!.text = "my text"
    return cell
}

Swift 3:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let identifier = "cell"
    let cell = tableView.dequeueReusableCell(withIdentifier: identifier) ??
        UITableViewCell(style: .default, reuseIdentifier: identifier)
    cell.textLabel!.text = "my text"
    return cell
}
 4
Author: david72,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-08 00:03:09

Cóż, zrobiłem tak:

Kroki dla UITableView za pomocą Swift :

  • Weź UITableView W ViewController
  • podaj referencję W ViewController.swift class
  • Give Outlets dataSource & deleguj do ViewController

Teraz Swift kod w ViewController.Klasa swift :

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var mTableView: UITableView!

    var items: [String] = ["Item 1","Item 2","Item 3", "Item 4", "Item 5"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.mTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.items.count;
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell:UITableViewCell = self.mTableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell

        cell.textLabel?.text = self.items[indexPath.row]
         println(self.items[indexPath.row])

        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        println("You have selected cell #\(indexPath.row)!")
    }
}

Teraz nadszedł czas, aby uruchomić swój program .

Done

 2
Author: Hiren Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-02 14:23:11

Właściwie w dokumencie przewodnika TableView firmy Apple i przykładowym kodzie znajdziesz zdanie poniżej:

Jeśli metoda dequeueReusableCellWithIdentifier: zapyta o komórkę zdefiniowaną w storyboardzie, metoda zawsze zwraca poprawną komórkę. Jeśli nie ma komórki z recyklingu czekającej na ponowne użycie, metoda tworzy nową, wykorzystując informacje w samym storyboardzie. Eliminuje to konieczność sprawdzania zwracanej wartości nil i tworzenia komórki ręcznie.

Więc możemy po prostu kodować tak:

var identifer: String = "myCell"
var cell = tableView.dequeueReusableCellWithIdentifier(identifer) as UITableViewCell
cell.textLabel.text = a[indexPath.row].name
cell.detailTextLabel.text = "detail"

Myślę, że jest to odpowiedni sposób użycia tableView

 1
Author: S.Captain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-01 02:44:06

Użycie słowa kluczowego "as" wykonałoby następujące dwa kroki:
1.tworzenie opcjonalnej wartości, która zawiera zmienną UITableViewCell;
2.rozpakowywanie wartości opcjonalnej.

Więc,robiąc to

var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Component") as UITableViewCell

Otrzymamy" zwykłą " zmienną typu uitableviewcell: cell.Teoretycznie rzecz biorąc, można to zrobić.Ale następna linia

if (cell == nil) {}

Sprawia kłopoty, ponieważ w języku swift tylko opcjonalna wartość może być przypisana z nil.

Więc, aby rozwiązać ten problem, musisz komórka zmienna typu opcjonalnego. tak po prostu:
var cell = tableView.dequeueReusableCellWithIdentifier("Component") as? UITableViewCell

Użycie słowa kluczowego " as?"utworzyłoby zmienną opcjonalną, a to, niewątpliwie, może być przypisane z nil.

 1
Author: li_shengdm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-16 06:28:46

Dla szablonu komórki:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let myCell : youCell =  youCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
        return myCell
    }
 0
Author: Lola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-04 09:33:53

Bro, proszę spojrzeć na próbkę https://github.com/brotchie/SwiftTableView

 0
Author: haithngn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-07 09:32:08

Dlaczego nie to?

(proszę usunąć, jeśli nie jestem w celu...)

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    if let cell: UITableViewCell = theTableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as? UITableViewCell {
        // cell ok
    }else{
       // not ok
    }
}
 0
Author: Mk3d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-01 17:36:19

Zrobiłem w następujący sposób: aby pokazać detailTextLabel. wartość tekstowa

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let CellIdentifier: String = "cell"

    var cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as? UITableViewCell

    if cell == nil {
        cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: CellIdentifier)
    }

    //cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator

    // parse the value of records
    let dataRecord = self.paymentData[indexPath.row] as! NSDictionary

    let receiverName = dataRecord["receiver_name"] as! String
    let profession = dataRecord["profession"] as! String
    let dateCreated = dataRecord["date_created"] as! String
    let payAmount = dataRecord["pay_amount"] as! String

    println("payment \(payAmount)")
    cell!.textLabel?.text = "\(receiverName)\n\(profession)\n\(dateCreated)"
    cell!.detailTextLabel?.text = "$\(payAmount)"
    cell!.textLabel?.numberOfLines = 4

    return cell!

}// end tableview
 0
Author: Vinod Joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-30 12:46:38

UITableView Demo using Playground

//: Playground - noun: a place where people can play

import UIKit
import PlaygroundSupport

class TableviewDemoDelegate:NSObject,UITableViewDataSource,UITableViewDelegate {


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }

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

        var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath)

        if cell == nil {
            cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        }


        cell?.textLabel?.text = "Item \(indexPath.row+1)"

        return cell!
    }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You have selected cell #\(indexPath.row)!")

    }
}

var tableView = UITableView(frame:CGRect(x: 0, y: 0, width: 320, height: 568), style: .plain)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")

let delegate = TableviewDemoDelegate()
tableView.delegate = delegate
tableView.dataSource = delegate


PlaygroundPage.current.liveView = tableView
 0
Author: Kirit Vaghela,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 09:49:19

Przejrzałem twoje kody i najprawdopodobniej powodem awarii jest to, że próbujesz wpisać opcjonalną wartość, która nie jest przypisana

Teraz rozważ linię kodu poniżej

var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell

Gdy nie ma komórek w widoku tableview, nadal próbujesz typecast jako UITableView.Gdy kompilator próbuje wpisać wartość nil, napotykasz ten problem

Poprawne stwierdzenie powinno być

var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") 

Można użyć polecenia if else do wpisania wartości, które holds

 0
Author: Suryanarayan Sahu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-28 10:20:39

Wypróbuj ten kod

var cell:CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell") as CustomTableViewCell
cell.cellTitle.text="vijay"

Https://github.com/iappvk/TableView-Swift

 -3
Author: Vijay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-21 12:29:14