dequeueReusableCellWithIdentifier에 대한 두 가지 과부하가 있으며 한 대를 사용해야하는 시점을 결정하려고합니까?
forIndexPath 함수와 관련된 Apple 문서에는 “이 메소드는 인덱스 경로를 사용하여 테이블보기에서 셀의 위치에 따라 추가 구성을 수행합니다.”
그래도 어떻게 해석 해야할지 모르겠습니다.
답변
가장 중요한 차이점은 forIndexPath:
식별자에 클래스 또는 펜촉을 등록하지 않은 경우 버전이 주장하는 것입니다. 이 경우 이전 forIndexPath:
버전이 아닌 버전이 반환 nil
됩니다.
registerClass:forCellReuseIdentifier:
테이블 뷰로 보내 식별자에 대한 클래스를 등록합니다 . registerNib:forCellReuseIdentifier:
테이블 뷰로 보내 식별자에 대한 펜촉을 등록합니다 .
스토리 보드에서 테이블보기 및 셀 프로토 타입을 작성하는 경우 스토리 보드 로더는 스토리 보드에서 정의한 셀 프로토 타입을 등록합니다.
세션 200-WWDC 2012의 Cocoa Touch의 새로운 기능은forIndexPath:
약 8m30에서 시작 하는 (새로운) 버전에 대해 설명합니다 . “언제나 초기화 된 셀을 얻게 될 것입니다”라고 말합니다 (클래스 나 펜촉을 등록하지 않으면 충돌이 발생하지는 않습니다).
비디오는 또한 “해당 인덱스 경로에 적합한 크기가 될 것”이라고 말합니다. 아마도 이것은 테이블 뷰의 자체 너비를보고 델리게이트의 tableView:heightForRowAtIndexPath:
메소드를 정의 하여 셀을 반환하기 전에 셀의 크기를 설정한다는 것을 의미합니다 (정의 된 경우). 이것이 인덱스 경로가 필요한 이유입니다.
답변
dequeueReusableCellWithIdentifier:forIndexPath:
것입니다 항상 셀을 반환합니다. 기존 셀을 재사용하거나 새 셀을 작성하고 셀이 없으면 리턴합니다.
반면, 전통 dequeueReusableCellWithIdentifier:
은 셀이 존재하는 경우, 즉 재사용 할 수있는 셀이있는 경우 셀을 반환하고, 그렇지 않으면 nil을 반환합니다. 따라서 nil
가치 를 확인하기위한 조건을 작성해야합니다 .
iOS 6 이상에서만 사용할 수 dequeueReusableCellWithIdentifier:
있으므로 iOS 5 이하 버전을 지원하려는 경우 사용에 대한 질문에 답변dequeueReusableCellWithIdentifier:forIndexPath
답변
Apple이 왜 새로운 메소드 dequeueReusableCellWithIdentifier : forIndexPath :를 생성했는지 이해하지 못했습니다. 그들에 대한 문서는 완전하지 않으며 다소 오도합니다. 두 가지 방법을 구별 할 수있는 유일한 차이점은 이전 메소드가 식별자가 전달 된 셀을 찾지 못하면 nil을 반환 할 수 있다는 것입니다. 새로운 메소드는 반환 할 수없는 경우 충돌합니다. 세포. 식별자를 올바르게 설정하고 스토리 보드에서 셀을 만들면 두 방법 모두 셀을 반환합니다. 클래스 또는 xib를 등록하고 셀을 코드 또는 xib 파일로 만들면 두 메소드 모두 셀을 반환합니다.
답변
요약하자면 :
dequeueReusableCell(withIdentifier, for)
프로토 타입 셀에서만 작동합니다. 프로토 타입 셀이 없을 때 사용하려고하면 앱이 중단됩니다.
Hollemans M. 2016, 2 장 점검표, IOS Apprentice (5 판). pp : 156.
답변
동적으로 생성 된 콘텐츠를 사용하는 경우 두 가지를 모두 사용하는 것이 좋습니다. 그렇지 않으면 앱이 예기치 않게 중단 될 수 있습니다. 선택적 재사용 가능 셀을 검색하기 위해 고유 한 기능을 구현할 수 있습니다. 그렇다면 nil
보이지 않는 빈 셀을 반환해야합니다.
스위프트 3
// Extensions to UITableView
extension UITableView
{
// returns nil, if identifier does not exist.
// Otherwise it returns a configured cell for the given index path
open func tryDequeueReusableCell (
withIdentifier identifier: String,
for indexPath: IndexPath) -> UITableViewCell?
{
let cell = self.dequeueReusableCell(withIdentifier: identifier)
if cell != nil {
return self.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
}
return nil
}
}
그리고 빈 셀을 반환하는 확장 프로그램 :
// Extension to UITableViewCell
extension UITableViewCell
{
// Generates an empty table cell that is not visible
class func empty() -> UITableViewCell
{
let emptyCell = UITableViewCell(frame:CGRect(x:0, y:0, width:0, height:0))
emptyCell.backgroundColor = UIColor.clear
return emptyCell
}
}
그것을 사용하는 방법의 완전한 예 :
import Foundation
import UIKit
// A protocol is used to identify if we can configure
// a cell with CellData
protocol ConfigureAbleWithCellData
{
func configure(_ data: CellData)
}
class MyCustomTableViewCell :
UITableViewCell,
ConfigureAbleWithCellData
{
@IBOutlet weak var title:UILabel! = nil
func configure(_ data: CellData)
{
self.title.text = data.title
}
}
// This actually holds the data for one cell
struct CellData
{
var title:String = ""
var reusableId:String = ""
}
class CosmoConverterUnitTableViewController:
UIViewController,
UITableViewDelegate,
UITableViewDataSource
{
// Storage
var data = Array<Array<CellData>>()
func loadData()
{
var section1:[CellData] = []
var section2:[CellData] = []
section1.append(CellData(title:"Foo", reusableId:"cellType1"))
section2.append(CellData(title:"Bar", reusableId:"cellType2"))
data.append(section1)
data.append(section2)
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
{
return data[section].count
}
public func numberOfSections(in tableView: UITableView) -> Int
{
return data.count
}
func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard
indexPath.row < data[indexPath.section].count
else
{
fatalError("this can't be")
}
let cellData = data[indexPath.section][indexPath.row]
if let cell = tableView.tryDequeueReusableCell(
withIdentifier: cellData.reusableId,
for: indexPath)
{
if let configurableCell = cell as? ConfigureAbleWithCellData
{
configurableCell.configure(cellData)
}
else
{
// cell is not of type ConfigureAbleWithCellData
// so we cant configure it.
}
return cell
}
// id does not exist
return UITableViewCell.empty()
}
}