我有一个与对象相关联的UITableViewCell
,我需要知道这个单元格是否可见。从我所做的研究来看,这意味着我需要以某种方式访问包含它的UITableView
(从那里,有几种方法可以检查它是否可见)。因此,我想知道UITableViewCell
是否有指向UITableView
的指针,或者是否有其他方法从单元格中获取指针?
我有一个与对象相关联的UITableViewCell
,我需要知道这个单元格是否可见。从我所做的研究来看,这意味着我需要以某种方式访问包含它的UITableView
(从那里,有几种方法可以检查它是否可见)。因此,我想知道UITableViewCell
是否有指向UITableView
的指针,或者是否有其他方法从单元格中获取指针?
为避免检查iOS版本,需要从单元格视图向上迭代遍历其父视图,直到找到UITableView:
Objective-C
id view = [cellInstance superview];
while (view && [view isKindOfClass:[UITableView class]] == NO) {
view = [view superview];
}
UITableView *tableView = (UITableView *)view;
Swift
var view = cellInstance.superview
while (view != nil && (view as? UITableView) == nil) {
view = view?.superview
}
if let tableView = view as? UITableView {
tableView.beginUpdates()
tableView.endUpdates()
}
@property (weak, nonatomic) UITableView *tableView;
,并在 tableView:cellForRowAtIndexPath:
中设置 cell.tableView = tableView;
。 - Alejandro Ivánextension 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
}
}
view != nil
检查。尽管如此,代码仍然进行了优化。 - Orkhan AlikhanovUITableViewWrapperView
是UITableViewCell
的父视图。此外,UITableView
也是UITableViewWrapperView
的父视图。
因此,在iOS 7中的解决方案如下:
UITableView *tableView = (UITableView *)cell.superview.superview;
UITableView *tableView = (UITableView *)cell.superview;
UITableViewCell
类别,其中包含一个新方法relatedTableView
,该方法检查iOS版本并返回适当的superView。 - memmonsiOS7之前,UITableViewCell的父视图是包含它的UITableView。从iOS7 GM版本开始(应该也会在公共版本中),UITableViewCell的父视图是一个名为UITableViewWrapperView的视图,其父视图是UITableView。有两种解决方案。
@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]
,并添加一个断言以确保如果视图层次结构在未来发生更改或还原,则会立即在测试中显示。
UITableViewCell
添加一个弱UITableView
引用@interface SOUITableViewCell
@property (weak, nonatomic) UITableView *tableView;
@end
这是一个更好的设计,但需要在现有项目中进行一些代码重构。在您的tableView:cellForRowAtIndexPath
中使用SOUITableViewCell
作为您的单元格类或确保您的自定义单元格类是从SOUITableViewCell
子类化并将tableView分配给单元格的tableView属性。在单元格内,您可以使用self.tableView
来引用包含的tableview。
[self.superview.superview isKindOfClass:[UITableView class]]
应该放在第一位,因为iOS 7越来越流行。 - CopperCashSwift 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
}
}
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
lookForSuperviewOfType:
方法体压缩成一行,使其更加 Swift 风格:return superview as? T ?? superview?.superviewOfType(type)
。 - kabiroberai@implementation UITableViewCell (ParentTableView)
- (UITableView *)parentTableView {
UITableView *tableView = nil;
UIView *view = self;
while(view != nil) {
if([view isKindOfClass:[UITableView class]]) {
tableView = (UITableView *)view;
break;
}
view = [view superview];
}
return tableView;
}
@end
您好,
以下是基于以上答案的Swift版本,我已经将其泛化为ExtendedCell
以供后续使用。
import Foundation
import UIKit
class ExtendedCell: UITableViewCell {
weak var _tableView: UITableView!
func rowIndex() -> Int {
if _tableView == nil {
_tableView = tableView()
}
return _tableView.indexPathForSelectedRow!.row
}
func tableView() -> UITableView! {
if _tableView != nil {
return _tableView
}
var view = self.superview
while view != nil && !(view?.isKindOfClass(UITableView))! {
view = view?.superview
}
self._tableView = view as! UITableView
return _tableView
}
}
UITableView *tv = (UITableView *) self.superview.superview;
BuyListController *vc = (BuyListController *) tv.dataSource;
[cell superView]
可能是什么? - Chris Loonam