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, UITableViewCellStyleValue2와 UITableViewCellStyleSubtitle?

저는 하위 클래스를 만들고 싶지 않습니다. 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.