[iphone] UITableViewCell에서 UITableView를 얻는 방법?

나는이 UITableViewCell객체에 링크 된 나는 셀이 표시되는 경우 알 필요가있다. 내가 한 연구에서 이것은 내가 UITableView그것을 포함하는 것에 어떻게 든 접근해야 함을 의미 합니다 (거기에서 그것이 보이는지 확인하는 몇 가지 방법이 있습니다). 그래서에 UITableViewCell대한 포인터가 있는지 UITableView또는 셀에서 포인터를 얻는 다른 방법이 있는지 궁금합니다 .



답변

iOS 버전을 확인하지 않으려면 UITableView가 발견 될 때까지 셀의 뷰에서 수퍼 뷰를 반복적으로 확인합니다.

id view = [tableViewCellInstance superview];

while (view && [view isKindOfClass:[UITableView class]] == NO) {
    view = [view superview]; 
}

UITableView *tableView = (UITableView *)view;


답변

iOS7에서 베타 5 UITableViewWrapperViewUITableViewCell. 또한 UITableView의 수퍼입니다 UITableViewWrapperView.

따라서 iOS 7의 경우 솔루션은


UITableView *tableView = (UITableView *)cell.superview.superview;

따라서 iOS 6까지의 iOS의 경우 솔루션은


UITableView *tableView = (UITableView *)cell.superview;


답변

Swift 5 확장

재귀 적으로

extension UIView {
    func parentView<T: UIView>(of type: T.Type) -> T? {
        guard let view = superview else {
            return nil
        }
        return (view as? T) ?? view.parentView(of: T.self)
    }
}

extension UITableViewCell {
    var tableView: UITableView? {
        return parentView(of: UITableView.self)
    }
}

루프 사용

extension UITableViewCell {
    var tableView: UITableView? {
        var view = superview
        while let v = view, v.isKind(of: UITableView.self) == false {
            view = v.superview
        }
        return view as? UITableView
    }
}


답변

iOS7 이전에는 셀의 수퍼 뷰가 UITableView포함되었습니다. GM iOS7에 현재의 수퍼 셀이있다 (그래서 아마도 아니라 공개용 될 예정) UITableViewWrapperView의 수퍼은 인으로 UITableView. 문제에 대한 두 가지 해결책이 있습니다.

솔루션 # 1 : UITableViewCell카테고리 생성

@implementation UITableViewCell (RelatedTable)

- (UITableView *)relatedTable
{
    if ([self.superview isKindOfClass:[UITableView class]])
        return (UITableView *)self.superview;
    else if ([self.superview.superview isKindOfClass:[UITableView class]])
        return (UITableView *)self.superview.superview;
    else
    {
        NSAssert(NO, @"UITableView shall always be found.");
        return nil;
    }

}
@end

이것은을 (를) 사용하기위한 좋은 드롭 인 대체물 cell.superview이며 기존 코드를 쉽게 리팩터링 할 수 있습니다. 검색하고로 바꾸고 [cell relatedTable]어설 션을 던져 뷰 계층 구조가 나중에 변경되거나 되돌릴 경우 즉시 표시되도록합니다. 당신의 테스트에서.

솔루션 # 2 : 약한 UITableView참조 추가UITableViewCell

@interface SOUITableViewCell

   @property (weak, nonatomic) UITableView *tableView;

@end

기존 프로젝트에서 사용하려면 더 많은 코드 리팩토링이 필요하지만 훨씬 더 나은 디자인입니다. 당신에 tableView:cellForRowAtIndexPath휴대 클래스로 사용 SOUITableViewCell 또는 있는지 확인하여 사용자 정의 셀 클래스에서 서브 클래스되는 SOUITableViewCell셀의있는 tableView 속성에있는 tableView를 할당합니다. 그런 다음 셀 내부에서를 사용하여 포함하는 tableview를 참조 할 수 있습니다 self.tableView.


답변

보이는 경우 수퍼 뷰가있는 것입니다. 그리고 … 놀랍게도 … superview는 UITableView 객체입니다.

그러나 수퍼 뷰가 있다고해서 화면에 있다는 보장은 없습니다. 그러나 UITableView는 표시되는 셀을 결정하는 방법을 제공합니다.

그리고 아니요, 셀에서 테이블로의 전용 참조가 없습니다. 그러나 UITableViewCell을 하위 클래스로 만들 때 하나를 도입하고 생성시 설정할 수 있습니다. (저는 하위 뷰 계층 구조를 생각하기 전에 많이했습니다.)

iOS7 업데이트 :
Apple은 여기에서 하위보기 계층 구조를 변경했습니다. 상세하게 문서화되지 않은 작업을 할 때 평소처럼 상황이 변경 될 위험이 항상 있습니다. UITableView 개체가 결국 발견 될 때까지 뷰 계층 구조를 “크롤링”하는 것이 훨씬 절약됩니다.


답변

Swift 2.2 솔루션.

특정 유형의 뷰를 재귀 적으로 검색하는 UIView의 확장입니다.

import UIKit

extension UIView {
    func lookForSuperviewOfType<T: UIView>(type: T.Type) -> T? {
        guard let view = self.superview as? T else {
            return self.superview?.lookForSuperviewOfType(type)
        }
        return view
    }
}

또는 더 콤팩트 (kabiroberai 덕분에) :

import UIKit

extension UIView {
    func lookForSuperviewOfType<T: UIView>(type: T.Type) -> T? {
        return superview as? T ?? superview?.superviewOfType(type)
    }
}

당신의 세포에서 당신은 그것을 부릅니다.

let tableView = self.lookForSuperviewOfType(UITableView)
// Here we go

UITableViewCell은 cellForRowAtIndexPath 실행 후에 만 ​​UITableView에 추가됩니다.


답변

수퍼 뷰를 호출하거나 응답자 체인을 통해 관리 할 수있는 모든 작업은 매우 취약 할 것입니다. 이를 수행하는 가장 좋은 방법은 셀이 무언가를 알고 자하는 경우, 셀이 묻고 자하는 질문에 답하는 방법에 응답하는 객체를 셀에 전달하고 컨트롤러가 응답 할 내용을 결정하는 논리를 구현하도록하는 것입니다. (귀하의 질문에서 나는 세포가 무언가가 보이는지 아닌지 알고 싶어한다고 생각합니다).

셀에 델리게이트 프로토콜을 생성하고, 셀의 델리게이트를 tableViewController로 설정하고 tableViewCotroller에서 모든 UI “제어”로직을 이동합니다.

테이블 뷰 셀은 정보 만 표시하는 덤 뷰 여야합니다.