【问题标题】:Showing/Hiding button in custom cell on demand not working按需在自定义单元格中显示/隐藏按钮不起作用
【发布时间】:2014-07-17 09:00:56
【问题描述】:

我正在尝试在我的表格视图中的某些单元格上显示一个按钮,具体取决于该单元格中显示的图像类型

我有两个 NSMutableArray,一个保存缩略图 URL,另一个 NSMutableArray 保存 URL 的类型(如果它是图像或视频)

问题是按钮未显示在所有视频类型单元格上

这是我的代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"TVCustomCell";

TVCustom *cell = (TVCustom *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"TVCustom" owner:self options:nil];
    for (id currentObject in topLevelObjects) {
        if ([currentObject isKindOfClass:[TVCustom class]]) {
            cell = (TVCustom *) currentObject;
            break;
        }
    }
}

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSString *imgURL = [arrayImagesURL objectAtIndex:indexPath.row];
    NSURL *imageURL = [NSURL URLWithString:imgURL];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];

    dispatch_async(dispatch_get_main_queue(), ^{
        UIImage *image = [UIImage imageWithData:imageData];
        cell.thumbImg.image = image;
    });
});

NSString *MediaType = [NSString stringWithFormat:@"%@", [arrayType objectAtIndex:indexPath.row]];

if ([MediaType isEqualToString:@"video"]) {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(120, 319, 50, 30);
    [button setTitle:@"Play" forState:UIControlStateNormal];
    button.tag = indexPath.row;
    [button addTarget:self action:@selector(PlayBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    button.backgroundColor= [UIColor clearColor];
    [cell.contentView addSubview:button];
}

return cell;
}

我不知道我做错了什么,知道吗?

【问题讨论】:

  • 一次检查 button.frame = CGRectMake(120, 319, 50, 30);这个按钮的框架 y 坐标从 319 开始检查它。
  • @Sunny 是的,我的自定义单元格高度是 350,我的按钮在单元格的底部,它不在单元格框架之外
  • 为什么每次都分配按钮,即使你有自己的自定义单元格TVCustom。在 TVCustom 上添加按钮并根据 MediaType 隐藏或显示。
  • 一旦检查断点天气是否被执行?
  • @trick14 已经这样做了,但遇到了同样的问题

标签: ios objective-c xcode uitableview


【解决方案1】:

我在这里看到了不同的问题。

首先

每次用户在 tableView 中滚动时,您的代码都会创建新按钮。这是因为您使用 dequeueReusableCellWithIdentifier 非常棒,它会返回现有单元格而不是创建新单元格。

然后你在已经存在的单元格上添加一个新按钮(可能有也可能没有按钮)

[cell.contentView addSubview:button];

我建议你在 TVCustom 类中添加按钮:

在 TVCustom.h 中

@property (strong, nonatomic) UIButton *viedoButton;

在 TVCustom.m 中

- (UIButton *)videoButton
{
    if (!_videoButton) {
        _videoButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        _videoButton.frame = CGRectMake(120, 319, 50, 30);
        [_videoButton setTitle:@"Play" forState:UIControlStateNormal];
        [_videoButton addTarget:self action:@selector(PlayBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        _videoButton.backgroundColor= [UIColor clearColor];
        [self.contentView _videoButton];
    }
    return _videoButton;
}

然后在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 你只做:

if ([MediaType isEqualToString:@"video"]) {
    cell.videoButton.hidden = NO;
} else {
    cell.videoButton.hidden = YES;
}

这样,每个单元格将只有一个按钮,并且仅在您需要时才可见,但不会每次都重新分配。但是PlayBtnClicked 必须在您的TVCustom 类中并且通过委托调用您的viewController

第二

您不应在 cellForRowAtIndexPath 方法中处理图像的加载。将其封装在您的 TVCustom 类中:

在 TVCustom.h 中

@property (strong, nonatomic) NSString *imgURL;

在 TVCustom.m 中

- (void)setImgURL:(NSString *)imgURL
{
    _imgURL = imgURL;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

         NSURL *imageURL = [NSURL URLWithString:imgURL];
         NSData *imageData = [NSData dataWithContentsOfURL:imageURL];

         dispatch_async(dispatch_get_main_queue(), ^{
             UIImage *image = [UIImage imageWithData:imageData];
             self.thumbImg.image = image;
         });
    });
 }

然后在cellForRowAtIndexPath 中看起来像:

cell.imgURL = [arrayImagesURL objectAtIndex:indexPath.row];

第三

我不知道您是否有任何特殊原因:

if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"TVCustom" owner:self options:nil];
    for (id currentObject in topLevelObjects) {
        if ([currentObject isKindOfClass:[TVCustom class]]) {
            cell = (TVCustom *) currentObject;
            break;
        }
    }
}

但是一个很好的方法是在你的 viewController 的viewDidLoad(或其他方法)中:

NSString *identifier = @"TVCustomCell";
NSString *nibName = @"TVCustom";
UINib *cellNib = [UINib nibWithName:nibName];
[self.tableView registerNib:cellNib forCellReuseIdentifier:identifier];

您的最终代码应如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


    static NSString *CellIdentifier = @"TVCustomCell";

    TVCustom *cell = (TVCustom *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    cell.imgURL = [arrayImagesURL objectAtIndex:indexPath.row];

    if ([MediaType isEqualToString:@"video"]) {
        cell.videoButton.hidden = NO;
    } else {
        cell.videoButton.hidden = YES;
    }

    return cell;
}

【讨论】:

  • 按你说的做了,关于按钮,你的代码有很多错误,不正确,你能检查一下吗?,谢谢
  • 抱歉,我忘记将按钮变量名称更改为videoButton。如果您忘记在单元类中添加此方法,您可能会收到Undeclared selector PlayBtnClicked 警告。
  • 更新后您提供的代码仍然无法正常工作,错误 *** 由于未捕获的异常 'NSUnknownKeyException' 导致应用程序终止,原因:'[ setValue:forUndefinedKey:]: 这个类不是键 viedoButton 的键值编码兼容。 ,,你能运行代码并检查一下吗?
  • 成功了,谢谢,UINib *cellNib = [UINib nibWithName:nibName]; 应该是 UINib *cellNib = [UINib nibWithNibName:nibName bundle:nil] ; ,另一件事是我在笔尖上添加按钮并将其与文件所有者连接,这是错误的,当我删除它时它起作用了
  • 很好,抱歉我现在无法使用 XCode 进行测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多