나는이 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 UITableViewWrapperView
는 UITableViewCell
. 또한 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 “제어”로직을 이동합니다.
테이블 뷰 셀은 정보 만 표시하는 덤 뷰 여야합니다.