UITableView в Swift
Я изо всех сил пытаюсь понять, что не так с этим фрагментом кода. В настоящее время это работает в Objective-C, но в Swift это просто падает на первой строке метода. Он показывает сообщение об ошибке в журнале консоли: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 ответов:
см. Также Мэтт!--10-->, который содержит вторую половину раствора
давайте найдем решение без создания пользовательских подклассов или крупка
реальная проблема заключается в том, что Swift различает объекты, которые могут быть пустыми (
nil) и объекты, которые не могут быть пустыми. Если вы не зарегистрируете перо для вашего идентификатора, тоdequeueReusableCellWithIdentifierможет возвратитьnil.это означает, что мы должны объявить переменную как необязательно:
var cell : UITableViewCell?и мы должны бросить с помощью
as?не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
ответ Султана умный, но реальное решение:не называй
dequeueReusableCellWithIdentifier. Это была ваша ошибка с самого начала.этот метод полностью устарел, и я удивлен, что он официально не устарел; ни одна система, которая может вместить Swift (iOS 7 или iOS 8), не нуждается в нем для каких-либо целей.
вместо этого вызовите современный метод,
dequeueReusableCellWithIdentifier:forIndexPath:. Это имеет то преимущество, что никакие опционные не участвуют; вы гарантированный что ячейка будет возвращена. Все вопросительные и восклицательные знаки отпадают, вы можете использоватьletвместоvarпотому что существование клетки гарантировано, и вы живете в удобном, современном мире.вы должны, если вы не используете раскадровку, зарегистрировать таблицу для этого идентификатора заранее, зарегистрировав либо класс, либо перо. Обычное место, чтобы сделать это
viewDidLoad, который уже в виде таблицы вообще существовать.вот пример использования пользовательского класса клеток:
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 }но если вы используете раскадровку (что делает большинство людей), вам даже не нужно регистрировать представление таблицы в
viewDidLoad! Просто введите идентификатор ячейки в раскадровке, и вы хорошо идти сdequeueReusableCellWithIdentifier:forIndexPath:.
ответ @ Sulthan находится на месте. Одной из возможных модификаций удобства было бы привести ячейку как UITableViewCell!, а не 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 }теперь вы можете изменить переменную ячейки без принудительного разворачивания ее каждый раз. Будьте осторожны при использовании неявно развернутых опций. Вы должны быть уверены, что значение, к которому вы обращаетесь, имеет значение.
для получения дополнительной информации обратитесь к разделу "неявно развернутые дополнительные"Свифт Язык Программирования.
попробуйте это:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell cell.textLabel.text = "\(indexPath.row)" return cell }обратите внимание, что вы должны зарегистрировать вас
UITableViewCellи ID при создании экземпляра вашейUITableView:tableView.delegate = self tableView.dataSource = self tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
вот что я написал, чтобы заставить его работать...
сначала зарегистрируйте ячейку табличного представления с табличным представлением
self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")затем настроить 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 }затем я определил пользовательский подкласс ячейки write в нижней части файла (так как теперь это намного проще)
class MyTableViewCell : UITableViewCell { init(style: UITableViewCellStyle, reuseIdentifier: String!) { super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier) } }
здесь есть несколько ответов, но я не думаю, что любой из них идеален, потому что после объявления вы получаете дополнительный UITableViewCell, который затем нуждается в
cell!...в любом толковании. Я думаю, что это лучший подход (я могу подтвердить, что это компилируется на Xcode 6.1):var cell:UITableViewCell if let c = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell { cell = c } else { cell = UITableViewCell() }
вот простой способ определить ячейку таблицы в 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 }
Ну, я сделал так:
шаги UITableView используя Свифт:
- забрать UITableView на ViewController
- дать Ссылки На Розетки на ViewController.Свифт класс
- Дать Точках источник & делегат до ViewController
теперь Свифт код в ViewController.Свифт класс:
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)!") } }теперь пришло время, чтобы запустить программу.
сделал
на самом деле в документе руководства Apple TableView и примере кода Вы найдете предложение ниже:
если метод dequeueReusableCellWithIdentifier: запрашивает ячейку, определенную в раскадровке, метод всегда возвращает допустимую ячейку. Если нет переработанной ячейки, ожидающей повторного использования, метод создает новую, используя информацию в самой раскадровке. Это устраняет необходимость проверки возвращаемого значения для nil и создания ячейки вручную.
Итак,мы могли бы просто код такой:
var identifer: String = "myCell" var cell = tableView.dequeueReusableCellWithIdentifier(identifer) as UITableViewCell cell.textLabel.text = a[indexPath.row].name cell.detailTextLabel.text = "detail"Я думаю, что это подходящий способ использовать tableView
используя ключевое слово "as", выполните следующие два шага:
1.создание необязательного значения, которое обертывает переменную UITableViewCell;
2.разворачивании необязательное значение.Итак,делая это
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Component") as UITableViewCellвы получите "простую" переменную типа UITableViewCell: cell.Теоретически говоря,это нормально.Но следующая строка
if (cell == nil) {}создает проблемы, потому что в swift только необязательное значение может быть назначено с нулем.
так, чтобы решите эту проблему, вы должны сделать ячейку переменной необязательного типа. вот так:
var cell = tableView.dequeueReusableCellWithIdentifier("Component") as? UITableViewCellиспользуя ключевое слово " как?"будет создана необязательная переменная, и это, несомненно, может быть присвоено нулю.
шаблон ячейки:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { let myCell : youCell = youCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell") return myCell }
братан, пожалуйста, взгляните на образец https://github.com/brotchie/SwiftTableView
почему не этот?
(пожалуйста, удалите, если я не в цель...)
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { if let cell: UITableViewCell = theTableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as? UITableViewCell { // cell ok }else{ // not ok } }
Я сделал следующим образом: чтобы показать detailTextLabel. текстовое значение
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
UITableView демо с помощью 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
Я прошел через ваши коды и, скорее всего, причина аварии заключается в том, что вы пытаетесь ввести необязательное значение, которое не назначено
теперь рассмотрим строку кода ниже
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCellкогда в tableview нет ячеек, вы все еще пытаетесь ввести как UITableView.Когда компилятор пытается ввести нулевое значение, вы сталкиваетесь с этой проблемой
правильное утверждение должно быть
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell")вы можете использовать оператор if else для typecast для значений, которые содержат
попробуйте этот код
var cell:CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell") as CustomTableViewCell cell.cellTitle.text="vijay"
Comments