简体   繁体   English

TableViewCell子视图在IOS 7中无法访问

[英]TableViewCell subviews can't access in IOS 7

I am using a customized TableViewCell in my App. 我在我的应用程序中使用自定义的TableViewCell It works fine with IOS 6 but I got error in ios 7. Error occurred when I access sub views of UITableViewCell 它在IOS 6上正常工作,但在ios 7中出现错误。当我访问UITableViewCell子视图时发生错误

see the code below where I got error 看到下面我出错的代码

- (void)addButtonClicked:(UIButton *)button {

    Product *product = [productsArray objectAtIndex:button.tag];
    NSString *code = product.code;
    OTATableCell *cell = (OTATableCell *) [[button superview] superview];

    cell.priceLabel; // here i get error

}

error shown is: 显示的错误是:

-[UITableViewCellScrollView priceLabel]: unrecognized selector sent to instance 0x15d0ff80

Please help me to solve this problem. 请帮我解决这个问题。 Thanks in advance. 提前致谢。

Need one more superView call: 还需要一个superView调用:

 OTATableCell *cell = (OTATableCell *)[[[button superview] superview] superview];

You can check something like: 您可以检查类似:

For iOS >= 7: 对于iOS> = 7:

       NSLog(@"%@",[[sender superview] class]);   //UITableViewCellContentView
       NSLog(@"%@",[[[sender superview] superview] class]); //UITableViewCellScrollView
       NSLog(@"%@",[[[[sender superview]superview]superview] class]);  //UITableViewCell

For iOS < 7: 对于iOS <7:

       NSLog(@"%@",[[sender superview] class]);   //UITableViewCellContentView
       NSLog(@"%@",[[[sender superview] superview] class]); //UITableViewCell
       NSLog(@"%@",[[[[sender superview]superview]superview] class]);  //UITableView

Edit:If you don't want to rely on superView property: 编辑:如果您不想依靠superView属性:

UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.table];
NSIndexPath *indexPath = [self.table indexPathForRowAtPoint:buttonFrame.origin];

//Access the cell using indexPath : //使用indexPath访问单元格:

UITableViewCell *cell=[self.table cellForRowAtIndexPath:indexPath];
   cell.label=@"setText";

Problem is Table view cells sub views. 问题是表视图单元格子视图。 In ios 7 there is one extra content view so you need to check for one more super view 在ios 7中,有一个额外的内容视图,因此您需要检查另一个超级视图

float fVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
    if(fVersion>=7.0)
    {
        OTATableCell *cell = (OTATableCell *)[[[button superview] superview] superview];
    }
    else
    {
        OTATableCell *cell = (OTATableCell *)[[button superview] superview];
    }

Or 要么

in cellForRowAtIndexPath, 在cellForRowAtIndexPath中,

set the Accessibility Identifier for the button which you are added on the cell as below 设置添加到单元格上的按钮的可访问性标识符,如下所示

[ button setAccessibilityIdentifier:[NSString stringWithFormat:@"%d",indexPath.row]]; [ button setAccessibilityIdentifier:[NSString stringWithFormat:@"%d",indexPath.row]];

Then where you want to access the cell use below code 然后在您要访问单元格的地方使用以下代码

NSIndexPath *iIndexRowId =[NSIndexPath indexPathForRow:[[button accessibilityIdentifier] intValue] inSection:0];
OTATableCell *objCell1=(OTATableCell*)[_YouTableName cellForRowAtIndexPath:iIndexRowId];

Obviously your problem is that Apple never promised you what the structure of a cell will be in different versions of iOS. 显然,您的问题是Apple从未向您保证过在不同版本的iOS中单元的结构会是什么。 So, it's a bad idea to rely on superview's superview. 因此,依靠Superview的SuperView是一个坏主意。 If you need to access a label in same cell as a button, keep the reference to it as a buttons property. 如果您需要在与按钮相同的单元格中访问标签,请将其引用保留为按钮属性。 I mean 我的意思是

@interface MyButton:UIButton 
@property (nonatomic, weak) UILabel* priceLabel;
@end

And assign this property when configure the cell. 并在配置单元格时分配此属性。

And remember: never hard cade versions! 记住:永远不要刻板的版本! Like <7.0 and >=7.0, because you don't know what version 8.0 will look like. 像<7.0和> = 7.0一样,因为您不知道8.0版本是什么样。

Relying on the order of sub views of any inbuilt control is not a good idea as its Apple's territory and they can change it anytime without any notice as they did in iOS 7. 依靠任何内置控件的子视图顺序不是一个好主意,因为它是Apple的领土,他们可以随时更改它而无需发出任何通知,就像在iOS 7中一样。

You can inherit UIButton class and add a property of class NSIndexPath . 您可以继承UIButton类并添加类NSIndexPath的属性。 While creating the cell in cellForRowAtIndexPath: method assign the value of input parameter indexpath to this property. cellForRowAtIndexPath:创建单元格时,将输入参数indexpath的值分配给此属性。

When the button is tapped, use the method [tableView cellForRowAtIndexPath:indexPath] to get the cell. 点击按钮后,使用方法[tableView cellForRowAtIndexPath:indexPath]获取单元格。 This method returns the object of class UITableViewCell , and in your case, the custom cell class. 此方法返回UITableViewCell类的对象,在您的情况下返回自定义单元格类。

Hope this helps! 希望这可以帮助!

Though you have the correct answer but i strongly disagree doing juglry with superviews. 虽然您有正确的答案,但我强烈反对接受超级意见。 And more over going the standard OOPS way it is very easy to do desired customization. 通过标准的OOPS方法,不仅可以轻松进行所需的自定义。

you can create a uitableviewcell subclass 您可以创建一个uitableviewcell子类

do all initialization in its 在其中进行所有初始化

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

method and save and use reuseIdentifier to identify and change your cell appearance. 方法并保存并使用reuseIdentifier来识别和更改单元格外观。 this way you will have flexibility of adding n number of methods in your cell and still keeping your cell for row method clean. 这样,您将可以灵活地在单元格中添加n个方法,并且仍保持行方法的单元格干净。

You must not rely on the view hierarchy in classes that start with UI. 您不得在以UI开头的类中依赖视图层次结构。 The view hierarchy in those classes can and will change without notice. 这些类中的视图层次结构可以并且将随时更改,恕不另行通知。 Don't do the superview dance. 不要做监督舞蹈。 Maybe Apple will change the view hierarchy in iOS8 again. 也许Apple会再次更改iOS8中的视图层次结构。

There is a much better way to do this. 有一个更好的方法来执行此操作。 You can ask the tableView for the indexPath of a specific point in your tableview. 您可以向tableView询问tableview中特定点的indexPath。 You can get this point by converting the buttons frame. 您可以通过转换按钮框架获得这一点。 This will always work, because it does not rely on implementation details. 这将始终有效,因为它不依赖于实现细节。

You do it like this: 您可以这样做:

- (void)addButtonClicked:(UIButton *)button {
    CGPoint buttonOriginInTableView = [button convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonOriginInTableView];

    Product *product = [productsArray objectAtIndex:indexPath.row];
    NSString *code = product.code;

    OTATableCell *cell = (OTATableCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    cell.priceLabel;
}

You can access tableview cell based upon access, regardless of the version you are using in it.This Code will work independent of the OS it is running. 无论使用哪种版本,都可以基于访问权限访问tableview单元。此代码将独立于其正在运行的操作系统运行。

    UITableViewCell *cell;
UIView * targetView; 
        id superView = [targetView superview];
        while (![superView isKindOfClass:[UITableViewCell class]])
        {
            superView = [superView superview];
        }
        cell = (UITableViewCell *)superView;

Now cell holds UITableViewCell 现在cell保存UITableViewCell

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM