코드에서 커스텀 셀을 사용할 때 register(_:forCellReuseIdentifier:) 함수를 넣었다
전제
Xcode9.2
Swift4
문제
열별로 표시할 셀을 결정하는 델리게이트 메서드를 작성하여 해당 열에 어떤 셀을 사용할지 결정합니다.
extension ListViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(ListTableViewCell.self), for: indexPath) as? ListTableViewCell else {
fatalError("The dequeued cell is not instance of MealTableViewCell.")
}
///ここ以下省略
여기서 떨어진다.
guard let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(ListTableViewCell.self), for: indexPath) as? ListTableViewCell
오류 메시지
reason: 'unable to dequeue a cell with identifier Todolist_firebase.MyCell -
must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
원인과 해결책
아래의 넣어 잊어
tableView.register(ListTableViewCell.self, forCellReuseIdentifier: NSStringFromClass(ListTableViewCell.self))
register(_,identifier)의 Apple 공식 문서 에서는 여기서 소개되고 있습니다
func register(_ cellClass: AnyClass?,
forCellReuseIdentifier identifier: String)
セルを作成する前に、このメソッド(_:forCellReuseIdentifier :)を呼び出して、新しいセルをつくることをテーブルビューに伝えます。 指定されたタイプのセルが現在再利用キューにない場合、テーブルビューは提供された情報を使用して新しいセルオブジェクトを自動的に作成します。
즉 제1 인수에는 이 테이블 뷰로 사용하는 cell의 클래스를 등록해, 제2 인수에서는 재이용할 때의 명찰적인 서 위치에서 String형의 이름을 넣어 주세요라고 하는 것일까요
dequeueReusableCell(withIdentifier:for:)의 Apple 공식 문서
재사용 가능한 테이블 뷰 셀 객체를 반환하고 테이블에 추가하는 함수입니다.
이 함수는 제 1 인수가 String 형의 identifier 로 제 2 인수가 indexPath 이므로 몇번째의 셀을 대상으로 하고 있는가 하는 숫자가 돌려줍니다
제 1 인수에 주목하면 형태는 String형으로 되어 있어, 상기의 register 함수로 string로 등록한 것을 재이용할 수 있도록(듯이) 하고 있군요
func dequeueReusableCell(withIdentifier identifier: String,
for indexPath: IndexPath) -> UITableViewCell
공식 문서에서는 일부러 노란색으로 둘러싸인 Important에서
重要
このメソッドを呼び出す前に、register(_:forCellReuseIdentifier :)またはregister(_:forCellReuseIdentifier :)メソッドを使用してクラスまたはnibファイルを登録する必要があります。
라고 썼습니다.
코드 전체
부분 생략
덧붙여서 왜 register
함수의 제 2 인수로 NSStringFromClass(ListTableViewCell.self)
이렇게 하고 있는가 하면, NSStringFromClass
함수는 인수로 넣은 클래스를 String으로 해 돌려주는 함수이기 때문입니다
例
NSStringFromClass(ListTableViewCell.self)
↓
"Todolist_firebase.ListTableViewCell"
class ListViewController: UIViewController {
var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
//テーブルビュー
tableView = UITableView(frame: self.view.frame, style: .plain)
tableView.rowHeight = 100
tableView.delegate = self
tableView.dataSource = self
//NSStrignFromClassはクラスの名前をStringで返してくれる
tableView.register(ListTableViewCell.self, forCellReuseIdentifier: NSStringFromClass(ListTableViewCell.self))
self.view.addSubview(tableView)
}
}
extension ListViewController: UITableViewDelegate, UITableViewDataSource {
//セクションの数を設定
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
//行数 セクションによって行数が違う場合はsectionで場合分けをするUITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
//列ごとに表示するセルを決めるデリゲートメソッド
//UITableViewDataSource は主に Table View が表示するデータを与えるものです。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(ListTableViewCell.self), for: indexPath) as? ListTableViewCell else {
fatalError("The dequeued cell is not instance of MealTableViewCell.")
}
let item = items[indexPath.row]
cell.nameLabel.text = item.title
return cell
}
}
class ListTableViewCell: UITableViewCell {
//MARK: Properties
var nameLabel: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
}
override func layoutSubviews() {
super.layoutSubviews()
self.addSubview(nameLabel)
nameLabel.frame = CGRect(x: 110, y: 0, width: frame.width - 100, height: frame.height)
}
//MARK : method
private func commonInit() {
self.createNameLabel()
}
private func createNameLabel() {
nameLabel = UILabel(frame: CGRect.zero)
nameLabel.textAlignment = .left
nameLabel.font = UIFont.systemFont(ofSize: 20)
}
}
덤
애플 문서 가라앉다
指定した識別子のクラスを登録し、新しいセルを作成する必要がある場合、init(style:reuseIdentifier :)メソッドを呼び出してセルを初期化します。
既存のセルが再利用可能な場合、このメソッドは代わりにセルのprepareForReuse()メソッドを呼び出します。
라고 하는 것으로, prepareForReuse()
함수가 언제 사용되는지가 문서를 확인하는 것으로 알았습니다
Reference
이 문제에 관하여(코드에서 커스텀 셀을 사용할 때 register(_:forCellReuseIdentifier:) 함수를 넣었다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/nakagawa1017/items/1d2c37982bcc9692c402
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
열별로 표시할 셀을 결정하는 델리게이트 메서드를 작성하여 해당 열에 어떤 셀을 사용할지 결정합니다.
extension ListViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(ListTableViewCell.self), for: indexPath) as? ListTableViewCell else {
fatalError("The dequeued cell is not instance of MealTableViewCell.")
}
///ここ以下省略
여기서 떨어진다.
guard let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(ListTableViewCell.self), for: indexPath) as? ListTableViewCell
오류 메시지
reason: 'unable to dequeue a cell with identifier Todolist_firebase.MyCell -
must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
원인과 해결책
아래의 넣어 잊어
tableView.register(ListTableViewCell.self, forCellReuseIdentifier: NSStringFromClass(ListTableViewCell.self))
register(_,identifier)의 Apple 공식 문서 에서는 여기서 소개되고 있습니다
func register(_ cellClass: AnyClass?,
forCellReuseIdentifier identifier: String)
セルを作成する前に、このメソッド(_:forCellReuseIdentifier :)を呼び出して、新しいセルをつくることをテーブルビューに伝えます。 指定されたタイプのセルが現在再利用キューにない場合、テーブルビューは提供された情報を使用して新しいセルオブジェクトを自動的に作成します。
즉 제1 인수에는 이 테이블 뷰로 사용하는 cell의 클래스를 등록해, 제2 인수에서는 재이용할 때의 명찰적인 서 위치에서 String형의 이름을 넣어 주세요라고 하는 것일까요
dequeueReusableCell(withIdentifier:for:)의 Apple 공식 문서
재사용 가능한 테이블 뷰 셀 객체를 반환하고 테이블에 추가하는 함수입니다.
이 함수는 제 1 인수가 String 형의 identifier 로 제 2 인수가 indexPath 이므로 몇번째의 셀을 대상으로 하고 있는가 하는 숫자가 돌려줍니다
제 1 인수에 주목하면 형태는 String형으로 되어 있어, 상기의 register 함수로 string로 등록한 것을 재이용할 수 있도록(듯이) 하고 있군요
func dequeueReusableCell(withIdentifier identifier: String,
for indexPath: IndexPath) -> UITableViewCell
공식 문서에서는 일부러 노란색으로 둘러싸인 Important에서
重要
このメソッドを呼び出す前に、register(_:forCellReuseIdentifier :)またはregister(_:forCellReuseIdentifier :)メソッドを使用してクラスまたはnibファイルを登録する必要があります。
라고 썼습니다.
코드 전체
부분 생략
덧붙여서 왜
register
함수의 제 2 인수로 NSStringFromClass(ListTableViewCell.self)
이렇게 하고 있는가 하면, NSStringFromClass
함수는 인수로 넣은 클래스를 String으로 해 돌려주는 함수이기 때문입니다例
NSStringFromClass(ListTableViewCell.self)
↓
"Todolist_firebase.ListTableViewCell"
class ListViewController: UIViewController {
var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
//テーブルビュー
tableView = UITableView(frame: self.view.frame, style: .plain)
tableView.rowHeight = 100
tableView.delegate = self
tableView.dataSource = self
//NSStrignFromClassはクラスの名前をStringで返してくれる
tableView.register(ListTableViewCell.self, forCellReuseIdentifier: NSStringFromClass(ListTableViewCell.self))
self.view.addSubview(tableView)
}
}
extension ListViewController: UITableViewDelegate, UITableViewDataSource {
//セクションの数を設定
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
//行数 セクションによって行数が違う場合はsectionで場合分けをするUITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
//列ごとに表示するセルを決めるデリゲートメソッド
//UITableViewDataSource は主に Table View が表示するデータを与えるものです。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(ListTableViewCell.self), for: indexPath) as? ListTableViewCell else {
fatalError("The dequeued cell is not instance of MealTableViewCell.")
}
let item = items[indexPath.row]
cell.nameLabel.text = item.title
return cell
}
}
class ListTableViewCell: UITableViewCell {
//MARK: Properties
var nameLabel: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
}
override func layoutSubviews() {
super.layoutSubviews()
self.addSubview(nameLabel)
nameLabel.frame = CGRect(x: 110, y: 0, width: frame.width - 100, height: frame.height)
}
//MARK : method
private func commonInit() {
self.createNameLabel()
}
private func createNameLabel() {
nameLabel = UILabel(frame: CGRect.zero)
nameLabel.textAlignment = .left
nameLabel.font = UIFont.systemFont(ofSize: 20)
}
}
덤
애플 문서 가라앉다
指定した識別子のクラスを登録し、新しいセルを作成する必要がある場合、init(style:reuseIdentifier :)メソッドを呼び出してセルを初期化します。
既存のセルが再利用可能な場合、このメソッドは代わりにセルのprepareForReuse()メソッドを呼び出します。
라고 하는 것으로,
prepareForReuse()
함수가 언제 사용되는지가 문서를 확인하는 것으로 알았습니다
Reference
이 문제에 관하여(코드에서 커스텀 셀을 사용할 때 register(_:forCellReuseIdentifier:) 함수를 넣었다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nakagawa1017/items/1d2c37982bcc9692c402텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)