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
}
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
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:
.
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 .
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")
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)
}
}
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()
}
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
}
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
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
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.
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 }
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
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
}
}
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
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
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
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"
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