iOS 6 UITableView dequeueReusableCellWithIdentifier : forIndexPath를 사용할 때 UITableViewCell의 스타일 설정 :


82

UITableViewCellStyle.NET 용 iOS 6에서 새로운 방법을 사용할 때 를 설정하는 방법을 알아 보려고합니다 UITableView.

이전에는 호출 할 때 다른 유형의 기본 셀을 생성 UITableViewCell하도록 UITableViewCellStyle열거 형을 변경 initWithStyle:했지만 수집 할 수있는 항목에서는 더 이상 그렇지 않습니다.

UITableView상태에 대한 Apple 문서 :

반환 값 : 연관된 재사용 식별자가있는 UITableViewCell 객체. 이 메서드는 항상 유효한 셀을 반환합니다.

토론 : 성능상의 이유로 테이블 뷰의 데이터 소스는 일반적으로 tableView : cellForRowAtIndexPath : 메서드의 행에 셀을 할당 할 때 UITableViewCell 객체를 재사용해야합니다. 테이블보기는 데이터 소스가 재사용을 위해 표시 한 UITableViewCell 오브젝트의 큐 또는 목록을 유지합니다. 테이블보기에 대한 새 셀을 제공하라는 메시지가 표시되면 데이터 소스 개체에서이 메서드를 호출합니다. 이 메서드는 사용 가능한 경우 기존 셀을 대기열에서 빼거나 ​​이전에 등록한 클래스 또는 nib 파일을 기반으로 새 셀을 만듭니다.

중요 :이 메서드를 호출하기 전에 registerNib : forCellReuseIdentifier : 또는 registerClass : forCellReuseIdentifier : 메서드를 사용하여 클래스 또는 nib 파일을 등록해야합니다.

지정된 식별자에 대한 클래스를 등록하고 새 셀을 만들어야하는 경우이 메서드는 initWithStyle : reuseIdentifier : 메서드를 호출하여 셀을 초기화합니다. 펜촉 기반 셀의 경우이 메서드는 제공된 펜촉 파일에서 셀 개체를로드합니다. 기존 셀을 재사용 할 수있는 경우이 메서드는 대신 셀의 prepareForReuse 메서드를 호출합니다.

이것이 cellForRowAtIndexPath새로운 방법을 구현 한 후 내 새로운 모습입니다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell_identifier";

    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    return cell;
}

지금까지 가지고있는 코드는 잘 작동하지만 항상 기본 스타일을 반환합니다. 어떻게 내가 같은 다른 스타일로 세포를 만들 수 있도록 변경할 수 있습니다 UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2UITableViewCellStyleSubtitle?

저는 하위 클래스를 만들고 싶지 않습니다. UITableViewCelliOS 6 이전에 할 수 있었던 것처럼 기본 유형을 변경하고 싶습니다. Apple이 향상된 메서드를 제공하지만 구현을 지원하기 위해 최소한의 문서 만 제공하는 것이 이상합니다.

누구든지 이것을 마스터했거나 비슷한 문제에 빠졌습니까? 합리적인 정보를 찾기 위해 고군분투하고 있습니다.

답변:


106

나는 당신이 서브 클래스를 만들고 싶지 않다고 말했지만 그것은 불가피 해 보인다. iOS 6.0 시뮬레이터에서 테스트하는 동안 어셈블리 코드를 기반으로 다음을 수행하여 UITableView새 인스턴스 UITableViewCell(또는 하위 클래스)를 만듭니다.

[[<RegisteredClass> alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:<ReuseIdentifier>]

즉, 전송 된 스타일 ( UITableViewCellStyleDefault)이 하드 코딩 된 것처럼 보입니다. 이 문제를 해결하려면 기본 이니셜 라이저를 재정의하고 initWithStyle:reuseIdentifier:사용하려는 스타일을 전달 하는 하위 클래스를 만들어야합니다 .

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    // ignore the style argument, use our own to override
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
    if (self) {
        // If you need any further customization
    }
    return self;
}

또한, 보내 더 좋을 수도 registerClass:forCellReuseIdentifier:에서 viewDidLoad대신에게 셀이 요청 될 때마다 일을 :

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerClass:<RegisteredClass> forCellReuseIdentifier:<ReuseIdentifier>];
}

4
나는 이것이 실제로 그럴 것이라고 생각하기 시작했다. 큰 문제는 아니지만 UITableViewCell다른 기본 스타일을 얻기 위해 하위 클래스 를 생성하는 것은 불필요한 파일을 생성하기 때문에 고통 스럽습니다. 귀하의 의견과 의심을 확인해 주셔서 감사합니다.
CaptainRedmuff 2011

11
서브 클래 싱 대신 여전히 유효한 이전 iOS5 메서드를 사용할 수 있다는 것을 잊지 마십시오. 이렇게하면 원하는 모든 유형의 셀 스타일을 초기화 할 수 있습니다. 다른 답변을 참조하십시오.
SpacyRicochet 2013 년

60

dequeueReusableCellWithIdentifier는 더 이상 사용되지 않으므로 new를 사용할 필요가 없습니다 dequeueReusableCellWithIdentifier:forIndexPath:.

사용자 지정 셀 클래스를 사용하고 있지만 UITableViewCellStyle 열거 형 중 하나를 사용하려는 경우 이전 방식을 사용하는 경우 적절한 등록 메서드 (viewDidLoad에서)와 함께 새로운 방식을 사용합니다.


1
멋진 새 방법 사용할 필요가 없다는 점에 찬성했습니다 . 목적에 맞거나 대안이 더 이상 사용되지 않는 경우에만.
SpacyRicochet 2013 년

특히 예민한 경우 dequeueReusableCellWithIdentifier:forIndexPath:이전 방식으로 셀을 빌드하고 반환하는 일부 식별자를 제공 하도록 재정의 하는 것이 좋습니다. 다른 식별자는 super를 호출하고이를 반환합니다. 그런 NSDictionary종류의 식별자에 대한 생성자 블록에 대한 식별자 를 갖는 것이 합리적 일 수 있습니다 .
Benjohn 2015 년

11

스토리 보드 인터페이스 빌더를 사용하여 불필요한 하위 클래스를 피할 수 있습니다.

  1. 스토리 보드보기에서 테이블보기 셀 프로토 타입 셀 (테이블보기에서)을 선택하십시오.
  2. 유틸리티보기의 속성 관리자에서 스타일 값을 수정하십시오.
  3. (선택 사항) 선택 및 액세서리와 같은 다른 값 수정

새로운 iOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath:은 새 셀을 할당하고 반환 할 때 이러한 값을 사용합니다. (Xcode 4.5.2를 사용하여 iOS 6.0 컴파일에서 테스트 됨)


7

하나의 파일을 저장하는 또 다른 대안은 Nib을 만들어 registerNib:forCellReuseIdentifier:대신 사용하는 것입니다.

Nib 만들기는 쉽습니다 : Interface Builder에서 새 .xib 파일을 만듭니다. 기본보기를 삭제하십시오. 테이블보기 셀 개체를 추가합니다. Attributes Inspector를 사용하여 셀의 스타일을 변경합니다. (여기에서 다른 속성을 조정하여 셀을 추가로 사용자 정의 할 수도 있습니다.)

그런 다음 테이블 뷰 컨트롤러의 viewDidLoad메서드에서 다음과 같이 호출합니다.

[self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"];

initWithStyle : reuseIdentifier가 호출되지 않습니다.
thierryb

0

Bolot의 대답이 맞습니다. 간단하며 XIB 파일을 만들 필요가 없습니다.

Objective-C 대신 Swift를 사용하는 사람에 대한 답변을 업데이트하고 싶었습니다.

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

-5

이에 대한 내 해결책 initWithStyle: reuseIdentifier:은 .NET을 사용하여 얻은 후 전화 하는 것 [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]입니다. 결국, init는 또 다른 선택 자일 뿐이며 컴파일러는 이미 초기화 된 객체에서 호출하는 데 제한을 두지 않습니다. 그러나 init 호출 결과를 사용하지 않는 것에 대해 불평 할 것이므로 다음과 같이합니다.

UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath];
cell = [cell initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellId"];

나는 이것이 Swift에서 작동하지 않을 것이라고 상상합니다 ...


가장 우아한 솔루션 imo. 바라건대 initWithStyle의 내장이 모든 것을 다시 생성하지는 않습니다.
Scott Birksted 2015

2
글쎄요, 만약 당신이 이렇게한다면, 당신은 대기열에서 빼는 것들을 모두 제거 할 수있을 것 같아요 ...
stk

1
셀을 재사용하는 것은 뛰어난 UITableView의 핵심입니다. 귀하의 솔루션은 세포를 재사용하지 말 것을 제안합니다.
Berik

2
initWithStyle: reuseIdentifier두 번째로 전화 하면 실제로 새로 생성 된 개체로 셀을 덮어 쓰게됩니다. 예, 메모리 할당이 이미 완료되었으며 새 셀이 동일한 메모리 위치를 덮어 쓰겠지만 실제로는 다시 초기화 할 때 완전히 새로운 객체를 생성합니다. 이것은 처음에 셀을 재사용하는 전체 지점 인 모든 최적화를 무효화합니다.
AnthonyMDev

1
안 좋은 해결책이 따를 -이 솔루션을 사용하는 경우, 나는 그것이 전부 세포를 대기열에서 삭제하는 것이 좋습니다 적어도 생각
Sudara
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.