【问题标题】:Animate button on UITableViewCell without affecting other UITableViewCellsUITableViewCell 上的动画按钮而不影响其他 UITableViewCell
【发布时间】:2014-10-20 04:38:27
【问题描述】:

我有一个带有以下代码的 UITableViewCell,其中用户单击 UITableViewCell 上的“保存”按钮。单元格中的图像被保存,“保存”按钮被动画化,但单元格仍然存在。

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

  if (!self.tableCell)
    {
        [tableView registerNib:[UINib nibWithNibName:@"LPContentTableViewCell" bundle:nil] forCellReuseIdentifier:@"ContentCell"];

        self.tableCell = [tableView dequeueReusableCellWithIdentifier:@"ContentCell"];
    }

        [self.tableCell.saveImageButton addTarget:self action:@selector(saveImage:) forControlEvents:UIControlEventTouchUpInside];

        return self.tableCell;

    }

    -(void)saveImage:(id)sender{

     UIButton *button = (UIButton*)sender;

    //image is saved

    [UIView animateWithDuration:0.5f animations:^{
            button.frame = newFrame;
        }completion:^(BOOL finished) {

                [button removeFromSuperview];


    }];

问题是,在我按下保存时未分配的单元格也丢失了保存按钮。我将按钮设置为发件人。该按钮被删除,接下来几个单元格上的按钮仍然存在。但是,当我在没有按钮的情况下滚动时,会出现 UITableView 中更下方的单元格。想法?

编辑:纳入建议

UIButton * cellButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cellButton setTitle:@"Save" forState:UIControlStateNormal];
[cellButton addTarget:self action:@selector(saveImage:) forControlEvents:UIControlEventTouchUpInside];
cellButton.frame = CGRectMake(268, 95, 79, 23);
[self.tableCell.contentView addSubview:cellButton];


-(void)saveImage:(id)sender{
UIButton *button = (UIButton*)sender;


CGRect newFrame = button.frame;

newFrame.origin.x +=100;

[UIView animateWithDuration:0.5f animations:^{
   button.frame = newFrame;

}completion:^(BOOL finished) {

        [button removeFromSuperview];

}];

【问题讨论】:

  • 带有标识符方法的cell alloc or deque cell在哪里
  • 在 cellForRow 中。为简洁起见,最初省略。在上面添加。
  • 为每个单元格创建按钮并添加标签并进行相应检查。
  • UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [按钮 addTarget:self action:@selector(aMethod:) forControlEvents:UIControlEventTouchUpInside];这需要来那个地方而不是你的 [self.tableCell.saveImageButton addTarget:self action:@selector(saveImage:) forControlEvents:UIControlEventTouchUpInside];或者去自定义单元格并使用委托来调用按钮
  • 但这之后会发生什么?我知道这一行,但因为现在它不是我不能做的属性 [cell.view removeFromSuperview];它有动画效果,但永远不会被移除。

标签: ios objective-c iphone uitableview


【解决方案1】:

您的实现打破了 MVC 模式。

cellForIndexPath 会在单元格将要显示在屏幕上时被调用,并且应该避免需要记住有关模型(图像)的任何内容。使用 indexPaths 在方法中访问您的模型。

实现这一点的正确方法是将其分开。

-(void) viewDidLoad
{
    [super viewDidLoad];

    // Register you nib here. You only need to do this once.
    [self.tableView registerNib:[UINib nibWithNibName:@"LPContentTableViewCell" bundle:nil] forCellReuseIdentifier:@"ContentCell"];
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Dequeuing will create or reuse cell. This is what that iOS silky smooth scrollin is all about
    LPContentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContentCell" forIndexPath: indexPath];

    BOOL canSave = YES; //figure out if image at indexPath can be saved..

    NSArray *targets = [cell.saveImageButton actionsForTarget:self forControlEvent:UIControlEventTouchUpInside];

    if ([targets count] == 0) {
        // Only add the target once per cell.. it would be easier to just add the target in IB instead of this method.
        [cell.saveImageButton addTarget:self action:@selector(saveImage:) forControlEvents:UIControlEventTouchUpInside];
    }


    if (canSave) {
        cell.saveImageButton.alpha = 1;
    }
    else {
        cell.saveImageButton.alpha = 0;
    }
}

-(void)saveImage:(id)sender {
    UIButton *button = (UIButton*)sender;
    LPContentTableViewCell *cell = [button superview];
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

    // Get image using indexPath and Save

    CGRect newFrame = button.frame;
    newFrame.origin.x +=100;

    [UIView animateWithDuration:0.5f animations:^{
       button.frame = newFrame;

    }completion:^(BOOL finished) {

        // Use alpha instead of removing the view so reused cells can just set the alpha back to 1
        button.alpha = 0;

        // Set the old frame back here too for reused cells.
        button.frame = oldFrame;
    }];
}

LPContentTableViewCell 的界面应该是这样的。

@interface LPContentTableViewCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UIButton *saveImageButton;  // This needs to be connected with IB

@end

【讨论】:

  • 似乎在单元格注册或重用方面存在问题,所以我不得不这样做 if (!cell) cell = [tableView dequeueReusableCellWithIdentifier:@"ContentCell"];单元格分配,但它的属性不再存在
  • 我的错误,其他出列方法总是返回一个有效的单元格。我会更新的。
  • 它可以工作,但我必须以编程方式向单元格添加子视图,因为单元格的属性记录为空。似乎有点不对劲,我无法弄清楚。你能更新一下你的实现是如何工作的吗?
  • 您需要将 Interface Builder 中的按钮连接到代码中的 IBOutlets。在助手视图中打开 Xcode 并将按钮连接到应该是 IBOutlet 的 saveImageButton
  • 他们是网点,但由于某种原因它不起作用。
【解决方案2】:

试试这个..

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

  if (!self.tableCell)
    {
        [tableView registerNib:[UINib nibWithNibName:@"LPContentTableViewCell" bundle:nil] forCellReuseIdentifier:@"ContentCell"];

        self.tableCell = [tableView dequeueReusableCellWithIdentifier:@"ContentCell"];
    }

           UIButton * cellButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
          [cellButton setTitle:@"Save" forState:UIControlStateNormal];
          [cellButton addTarget:self action:@selector(saveImage:) forControlEvents:UIControlEventTouchUpInside];
          cellButton.frame = CGRectMake(127, 8, 50, 30);
          [cell.contentView addSubview:cellButton];

        return self.tableCell;

    }

    -(void)saveImage:(UIButton*)sender{

    //image is saved

    [UIView animateWithDuration:0.5f animations:^{

        }completion:^(BOOL finished) {

                [sender removeFromSuperview];


    }];

【讨论】:

  • 如何识别调用的是哪个单元格
  • 有效,但对于 sender.frame - 我变红了。我认为另一个按钮被分配,因为一个按钮被动画和删除,但原始的“保存”单元按钮由于某种原因仍然存在。谢谢
  • 现在看看我的代码,你有没有通过故事板或笔尖添加任何按钮,如果是的话删除它们,我的代码对你有用别忘了接受答案...:)
  • 已尝试但仍无法正常工作 - 创建了一个具有动画效果的新按钮,但原始按钮保留在原位。
  • 你删除了你的 saveImageButton,你确定..?
【解决方案3】:

您需要以编程方式为每个单元格创建一个新按钮。

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self 
        action:@selector(aMethod:)
forControlEvents:UIControlEventTouchUpInside];`

你可以给它添加一个标签作为某种类型的标识符。

[button setTag:rowNumber];

【讨论】:

  • 所以,在 cellForRow 创建按钮。然后在 saveImage 中设置标签?我还需要转换 UIButton button = (UIButton)sender; 吗?
  • 设置cellForRow中按钮的标签。然后在单击按钮时调用的方法中访问该标记并使用它来获取具有 [tableView indexPathForCell:[(UIButton *)sender tag]]; 的单元格
  • 还是不明白。该方法将一个单元格作为参数并返回一个我已经拥有的 indexPath,因为它是按钮的标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
相关资源
最近更新 更多