codememo

dequeueReusableCellWithIdentifier vs dequeueReusableCellWithIdentifier : forIndexPath를 사용하는 경우

tipmemo 2023. 4. 18. 22:47
반응형

dequeueReusableCellWithIdentifier vs dequeueReusableCellWithIdentifier : forIndexPath를 사용하는 경우

dequeueReusableCellWithIdentifier에는 2개의 오버로드가 있으며, 어느 한쪽을 사용해야 하는지 다른 한쪽을 사용해야 하는지 판단하려고 합니다.

forIndexPath 함수에 관한 Apple 문서에는 "이 메서드는 인덱스 경로를 사용하여 테이블 뷰에서 셀의 위치에 따라 추가 설정을 수행합니다."라고 기술되어 있습니다.

어떻게 해석해야 할지 모르겠는데?

가장 중요한 차이점은 이 모든 것이forIndexPath:ID에 클래스 또는 니브를 등록하지 않은 경우 버전이 어설트(확장)됩니다.더 오래된 것(비-)forIndexPath:) 버전 반환nil그런 경우에는요.

ID에 대한 클래스를 등록하려면registerClass:forCellReuseIdentifier:테이블 뷰로 이동합니다.다음을 전송하여 식별자에 대한 니브를 등록합니다.registerNib:forCellReuseIdentifier:테이블 뷰로 이동합니다.

테이블 뷰와 셀 프로토타입을 스토리보드에 작성하는 경우 스토리보드 로더는 스토리보드에 정의한 셀 프로토타입을 등록합니다.

세션 200 - WWDC 2012의 코코아 터치 신기능에 대해서forIndexPath:버전 8m30s 이후."항상 초기화 된 셀이 표시됩니다(클래스나 니브를 등록하지 않은 경우 충돌한다는 설명 없음).

또한 비디오에는 "인덱스 경로에 적합한 크기가 될 것"이라고 나와 있습니다.이는 테이블 뷰의 너비를 보고 셀의 크기를 설정한 후 반환하는 것을 의미합니다.tableView:heightForRowAtIndexPath:method (정의되어 있는 경우)이것이 인덱스 경로가 필요한 이유입니다.

dequeueReusableCellWithIdentifier:forIndexPath:는 항상 셀을 반환합니다.기존 셀을 다시 사용하거나 새 셀을 생성하여 셀이 없는 경우 반환합니다.

한편, 기존의dequeueReusableCellWithIdentifier:는 셀이 존재하는 경우 셀을 반환합니다.즉, 재사용할 수 있는 셀이 있는 경우 셀은 0을 반환합니다.그래서 당신은 체크할 조건을 써야만 할 것이다.nil가치도 있습니다.

질문에 답하려면 다음을 사용하십시오.dequeueReusableCellWithIdentifier:이후 iOS 5 이하 버전을 지원하는 경우dequeueReusableCellWithIdentifier:forIndexPathiOS 6 이상에서만 사용 가능

참조: https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html #//apple_ref/occ/instm/UITableView/dequeueReusableCellWithIdentifier: forIndexPath:

Apple이 새로운 메서드인 dequeueReusableCellWithIdentifier:forIndexPath:를 만든 이유를 전혀 이해하지 못했습니다.이들에 대한 그들의 문서는 완전하지 않고 다소 오해의 소지가 있다.이 두 가지 방법을 구별할 수 있는 유일한 차이점은 식별자가 전달된 셀을 찾지 못하면 오래된 메서드가 0을 반환할 수 있고 새로운 메서드가 셀을 반환할 수 없으면 크래쉬할 수 있다는 것입니다.두 방법 모두 식별자를 올바르게 설정한 경우 셀을 반환하고 스토리보드에 셀을 만듭니다.두 방법 모두 클래스 또는 xib를 등록하고 코드 또는 xib 파일로 셀을 만들 경우 셀을 반환하는 것이 보증됩니다.

줄여서:

dequeueReusableCell(withIdentifier, for)프로토타입 셀에서만 작동합니다.프로토타입 셀이 없을 때 사용하려고 하면 앱이 크래시됩니다.

Hollemans M. 2016, 제2장 체크리스트, IOS 어프렌티스(5판)페이지: 156.

가장 큰 차이점은 재사용 식별자만 사용하여 동일한 indexPath에 2개의 셀을 등록할 수 없다는 것입니다.또한 셀이 해당 테이블뷰에 등록되어 있지 않으면 둘 다 0을 반환할 수 있습니다.

동적 생성 콘텐츠를 사용하는 경우 둘 다 사용할 것을 권장합니다.그렇지 않으면 앱이 예기치 않게 충돌할 수 있습니다.독자적인 기능을 실장하고, 옵션의 재사용 가능한 셀을 취득할 수 있습니다. 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()
    }
}

언급URL : https://stackoverflow.com/questions/25826383/when-to-use-dequeuereusablecellwithidentifier-vs-dequeuereusablecellwithidentifi

반응형