Swift의 UITableView
이 코드 조각의 문제점을 파악하기 위해 고군분투하고 있습니다. 이것은 현재 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
}
솔루션의 후반부를 포함하는 Matt의 답변 도 참조하십시오.
사용자 지정 하위 클래스 또는 펜촉을 만들지 않고 솔루션을 찾자
진짜 문제는 Swift가 비어있을 수있는 nil
객체 ( )와 비어 있을 수없는 객체를 구별한다는 사실입니다 . 당신이 당신의 식별자에 대한 펜촉을 등록하지 않는 경우, dequeueReusableCellWithIdentifier
반환 할 수 있습니다 nil
.
즉, 변수를 선택 사항으로 선언해야합니다.
var cell : UITableViewCell?
그리고 우리는 as?
notas
//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
Sulthan의 대답은 영리하지만 실제 해결책은 전화하지 마십시오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
}
이제 매번 강제로 풀지 않고 셀 변수를 수정할 수 있습니다. 암시 적으로 언 래핑 된 옵션을 사용할 때는주의하십시오. 액세스하는 값에 값이 있는지 확인해야합니다.
자세한 내용은 The Swift Programming Language 의 "암시 적으로 언 래핑 된 옵션"섹션을 참조하십시오 .
이 시도:
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
}
그런 다음 파일 맨 아래에 사용자 지정 셀 하위 클래스 쓰기를 정의했습니다 (이제 훨씬 쉬워 졌기 때문에).
class MyTableViewCell : UITableViewCell {
init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
}
}
다음은 신속한 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
}
스위프트 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
}
여기에 몇 가지 답변이 있지만 그 중 어떤 것도 이상적이라고 생각하지 않습니다. 선언 후에는 선택적인 UITableViewCell로 끝나고 cell!...
모든 선언 에서이 필요하기 때문 입니다. 나는 이것이 더 나은 접근 방식이라고 생각합니다 (이것이 Xcode 6.1에서 컴파일되었음을 확인할 수 있습니다).
var cell:UITableViewCell
if let c = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell {
cell = c
}
else {
cell = UITableViewCell()
}
글쎄, 나는 이렇게했다.
Swift를 사용 하는 UITableView 를 위한 단계 :
- ViewController 에서 UITableView 가져 오기
- ViewController.swift 클래스 에서 참조 아웃렛 제공
- 주고 아울렛 은 dataSource 및 위임 에 의 ViewController
이제 ViewController.swift 클래스의 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)!")
}
}
이제 프로그램 을 실행할 시간 입니다.
끝난
실제로 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) {}
신속하게 옵션 값만 nil로 할당 할 수 있기 때문에 문제가 발생합니다.
따라서이 문제를 해결하려면 셀을 선택형 변수로 만들어야합니다. 다음과 같이 :
var cell = tableView.dequeueReusableCellWithIdentifier("Component") as? UITableViewCell
키워드 "as?"사용 Optional 변수를 생성하고 의심 할 여지없이 이것은 nil로 할당 될 수 있습니다.
셀 템플릿의 경우 :
func tableView (tableView : UITableView !, cellForRowAtIndexPath indexPath : NSIndexPath!)-> UITableViewCell! { let myCell : youCell = youCell (style : UITableViewCellStyle.Subtitle, reuseIdentifier : "cell") 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
}
}
I have done in following way: to show detailTextLabel. text value
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 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
I went through your codes and most probably the reason for the crash is you are trying to typecast an optional value which is not assigned
Now consider the line of code below
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
When there are no cells in the tableview you are still trying to typecast as UITableView.When the compiler tries to typecast nil value you face this issue
The correct statement should be
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell")
You can use if else statement to typecast for values which holds
Try this code
var cell:CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell") as CustomTableViewCell
cell.cellTitle.text="vijay"
https://github.com/iappvk/TableView-Swift
참고URL : https://stackoverflow.com/questions/24022763/uitableview-in-swift
'Development Tip' 카테고리의 다른 글
자바에서 for 루프에서 벗어나기 (0) | 2020.12.02 |
---|---|
생년월일을 기준으로 연령 계산 (0) | 2020.12.02 |
iPhone X / 8 / 8 Plus CSS 미디어 쿼리 (0) | 2020.12.02 |
SQL Server의 VARCHAR에서 숫자가 아닌 문자를 제거하는 가장 빠른 방법 (0) | 2020.12.02 |
Eclipse : Android SDK를 사용할 수 없으며 ADT가 오래되었다고 잘못 주장합니다. (0) | 2020.12.02 |