Iphone 如何从UITableViewCell获取UITableView?
我有一个Iphone 如何从UITableViewCell获取UITableView?,iphone,ios,objective-c,xcode,tableview,Iphone,Ios,Objective C,Xcode,Tableview,我有一个UITableViewCell,它链接到一个对象,我需要知道该单元格是否可见。根据我所做的研究,这意味着我需要以某种方式访问包含它的UITableView(从那里,有几种方法可以检查它是否可见)。因此,我想知道UITableViewCell是否有指向UITableView的指针,或者是否有其他方法从单元格获取指针?如果它是可见的,那么它有一个超级视图。而且。。。惊喜superview是UITableView对象 然而,拥有superview并不能保证能出现在屏幕上。但UITableVie
UITableViewCell
,它链接到一个对象,我需要知道该单元格是否可见。根据我所做的研究,这意味着我需要以某种方式访问包含它的UITableView
(从那里,有几种方法可以检查它是否可见)。因此,我想知道UITableViewCell
是否有指向UITableView
的指针,或者是否有其他方法从单元格获取指针?如果它是可见的,那么它有一个超级视图。而且。。。惊喜superview是UITableView对象
然而,拥有superview并不能保证能出现在屏幕上。但UITableView提供了确定哪些单元格可见的方法
不,没有从单元格到表的专用引用。但当您将UITableViewCell子类化时,您可以引入一个并在创建时设置它。(在考虑子视图层次结构之前,我自己做了很多。)
iOS7的更新:
Apple已经更改了此处的子视图层次结构。与往常一样,在处理未详细记录的事情时,总是存在事情发生变化的风险。在最终找到UITableView对象之前,“向上爬网”视图层次结构是非常节省的 无论你最终通过调用super view或通过响应链来完成什么,都将是非常脆弱的。 如果细胞想知道一些事情,最好的方法是将一个对象传递给细胞,该对象对回答细胞想问的问题的某种方法作出响应,并让控制器实现确定要回答什么的逻辑(根据你的问题,我猜细胞想知道某些事情是否可见) 在单元格中创建委托协议,将单元格的委托设置为tableViewController,并移动tableViewController中的所有ui“控制”逻辑
表格视图单元格应为仅显示信息的dum视图 此代码
`UITableView*tblView=[cell superview]
将为您提供一个包含tabe view单元格的UItableview实例我基于Gabe的建议,即UITableViewWrapperView
对象是iOS7 beta5中UITableViewCell
对象的超级视图,提出了此解决方案
子类UITableviewCell:
- (UITableView *)superTableView
{
return (UITableView *)[self findTableView:self];
}
- (UIView *)findTableView:(UIView *)view
{
if (view.superview && [view.superview isKindOfClass:[UITableView class]]) {
return view.superview;
}
return [self findTableView:view.superview];
}
在iOS7 beta 5中,
UITableViewWrapperView
是UITableViewCell
的超级视图同样UITableView
是UITableViewWrapperView
的超级视图
因此,对于iOS 7,解决方案是
UITableView*tableView=(UITableView*)cell.superview.superview;
因此,对于iOS 6之前的损失,解决方案是
UITableView*tableView=(UITableView*)cell.superview;
我建议您以这种方式遍历视图层次结构,以找到父UITableView:
- (UITableView *) findParentTableView:(UITableViewCell *) cell
{
UIView *view = cell;
while ( view && ![view isKindOfClass:[UITableView class]] )
{
#ifdef DEBUG
NSLog( @"%@", [[view class ] description] );
#endif
view = [view superview];
}
return ( (UITableView *) view );
}
否则,当Apple再次更改视图层次结构时,您的代码将中断
也遍历层次结构的是递归的 为避免检查iOS版本,请从单元格视图中迭代遍历SuperView,直到找到UITableView:
id view = [tableViewCellInstance superview];
while (view && [view isKindOfClass:[UITableView class]] == NO) {
view = [view superview];
}
UITableView *tableView = (UITableView *)view;
在iOS7之前,单元格的超级视图是包含它的
UITableView
。截至iOS7 GM(因此可能也会在公开发行版中发布),单元的superview是一个UITableViewWrapperView
,其superview是UITableView
。这个问题有两种解决办法
解决方案#1:创建UITableViewCell
类别
这是对使用单元格的一个很好的替代。superview
,使重构现有代码变得很容易——只需搜索并替换为[cell relatedTable]
,并插入一个断言,以确保如果视图层次结构在将来更改或恢复,它将立即显示在测试中
解决方案2:向UITableView单元格添加一个弱的UITableView
引用
这是一个更好的设计,尽管它需要更多的代码重构才能在现有项目中使用。在tableView:cellForRowAtIndexPath
中,使用SOUITableViewCell作为单元格类,或者确保自定义单元格类是从SOUITableViewCell
中进行子类化的,并将tableView指定给单元格的tableView属性。在单元格内,您可以使用self.tableview
引用包含的tableview 我在UITableViewCell上创建了一个类别以获取其父表视图:
@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
最好使用[“UItableViewvariable”visibleCells]代替superview
我在foreach循环中使用它来循环应用程序看到的单元格,并且它工作了
for (UITableView *v in [orderItemTableView visibleCells])//visibleCell is the fix.
{
@try{
[orderItemTableView reloadData];
if ([v isKindOfClass:[UIView class]]) {
ReviewOrderTableViewCell *cell = (ReviewOrderTableViewCell *)v;
if (([[cell deleteRecord] intValue] == 1) || ([[[cell editQuantityText] text] intValue] == 0))
//code here
}
}
}
工作起来很有魅力。iOS 7中的UITableViewCell内部视图层次结构更改
UITableViewCell Internal View Hierarchy Change in iOS 7
Using iOS 6.1 SDK
<UITableViewCell>
| <UITableViewCellContentView>
| | <UILabel>
Using iOS 7 SDK
<UITableViewCell>
| <UITableViewCellScrollView>
| | <UIButton>
| | | <UIImageView>
| | <UITableViewCellContentView>
| | | <UILabel>
The new private UITableViewCellScrollView class is a subclass of UIScrollView and is what allows this interaction:
![enter image description here][1]
[1]: http://i.stack.imgur.com/C2uJa.gif
使用iOS 6.1 SDK
|
| |
使用iOS7SDK
|
| |
| | |
| |
| | |
新的私有UITableViewCellScrollView类是UIScrollView的一个子类,它允许这种交互:
![在此处输入图像描述][1]
[1]: http://i.stack.imgur.com/C2uJa.gif
谢谢你我从上面的答案中借用并修改了一点,并得出了以下片段
- (id)recursivelyFindSuperViewWithClass:(Class)clazz fromView:(id)containedView {
id containingView = [containedView superview];
while (containingView && ![containingView isKindOfClass:[clazz class]]) {
containingView = [containingView superview];
}
return containingView;
}
传入类为在某些其他情况下遍历和获取UITableView以外的视图提供了灵活性 我对这个问题的解决方案与其他解决方案有些相似,但使用了一个优雅的for循环,而且很短。它也应该是未来的证明:
- (UITableView *)tableView
{
UIView *view;
for (view = self.superview; ![view isKindOfClass:UITableView.class]; view = view.superview);
return (UITableView *)view;
}
以下是基于上述答案的Swift版本。我将其概括为ExtendedCell
,以供以后使用
<代码>导入基础
导入UIKit
类ExtendedCell:UITableViewCell{
弱var\u tableView:UITableView!
func rowIndex()->Int{
如果_tableView==nil{
_tableView=tableView()
}
返回_tableView.indexPathForSelectedRow!.row
}
func tableView()->UITableView{
如果
- (id)recursivelyFindSuperViewWithClass:(Class)clazz fromView:(id)containedView {
id containingView = [containedView superview];
while (containingView && ![containingView isKindOfClass:[clazz class]]) {
containingView = [containingView superview];
}
return containingView;
}
- (UITableView *)tableView
{
UIView *view;
for (view = self.superview; ![view isKindOfClass:UITableView.class]; view = view.superview);
return (UITableView *)view;
}
UITableView *tv = (UITableView *) self.superview.superview;
BuyListController *vc = (BuyListController *) tv.dataSource;
UITableView *tableView = (UITableView *)[[cell superview] superview];
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
extension UIView {
func parentTableView() -> UITableView? {
var viewOrNil: UIView? = self
while let view = viewOrNil {
if let tableView = view as? UITableView {
return tableView
}
viewOrNil = view.superview
}
return nil
}
}
extension UITableViewCell {
func tableView() -> UITableView? {
var currentView: UIView = self
while let superView = currentView.superview {
if superView is UITableView {
return (superView as! UITableView)
}
currentView = superView
}
return nil
}
}
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
}
}
extension UITableViewCell {
func relatedTableView() -> UITableView? {
var view = self.superview
while view != nil && !(view is UITableView) {
view = view?.superview
}
guard let tableView = view as? UITableView else { return nil }
return tableView
}