1

我正在尝试像苹果的闹钟这样的东西,当点击编辑按钮时,自定义视图会覆盖自定义UITableViewCell.

上面的代码:

 // CGRect frame = [tableView rectForRowAtIndexPath:indexPath];
    // CGPoint yOffset = self.tableViewBlock.contentOffset;
    // CGRect newFrame = CGRectMake(frame.origin.x, (frame.origin.y - yOffset.y + 45), frame.size.width, frame.size.height);
    CallBlock_Date_EditMode *viewController = [[CallBlock_Date_EditMode alloc] initWithNibName:@"CallBlock_Date_EditMode" bundle:nil];

    // self.view.frame = newFrame;
    // [self.view addSubview:viewController.view];
    // [self addChildViewController:viewController];

    UITableViewCell *cell = (UITableViewCell*)[self.tableViewBlock cellForRowAtIndexPath:indexPath];
    [cell.contentView addSubview:viewController.view];

当我输入时覆盖特定的单元格:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  • 只是为了确保大小没问题(尽管当我点击那个 xib 中的一个按钮时,应用程序崩溃,甚至没有一个错误)。

但我想像苹果的闹钟一样(实际上,模仿它),点击我的编辑按钮,我的自定义UITableViewCell将被这个 xib 作为视图覆盖。

也许有更好的方法来做到这一点?

编辑:

我更新的代码是:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    CallBlock_TableCell *cell = (CallBlock_TableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (cell == nil)
    {
        cell = [[CallBlock_TableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)configureCell:(CallBlock_TableCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    cell.accessoryType = self.isEditing ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;

    CallBlock_ByDate *callBlock = (CallBlock_ByDate*)[fetchedObjects objectAtIndex:indexPath.row];
    cell.labelTime.text = callBlock.startDate;
    cell.labelRepeat.text = callBlock.repeat;
    cell.labelTextLabel.text = callBlock.label;
    cell.switchCallBlock.on = YES;
    cell.switchCallBlock.tag = (NSInteger)indexPath.row +1;
    [cell.switchCallBlock addTarget:self action:@selector(handleSwitch:) forControlEvents:UIControlEventValueChanged];
    cell.switchCallBlock.hidden = self.isEditing ? YES : NO;

    if (self.isEditing)
    {
        cell.switchCallBlock.hidden = YES;
        UIButton *btnArrow = [[UIButton alloc] init];
        btnArrow.frame = CGRectMake(282.0, 31.0, 18.0, 21.0);
        [btnArrow setBackgroundImage:[UIImage imageNamed:@"arrow_FWR_off"] forState:UIControlStateNormal];
        [btnArrow setBackgroundImage:[UIImage imageNamed:@"arrow_FWR_on"] forState:UIControlStateHighlighted];
        btnArrow = [UIButton buttonWithType:UIButtonTypeCustom];
        [btnArrow addTarget:self action:@selector(handleTapToEdit:) forControlEvents:UIControlEventTouchUpInside];
        btnArrow.tag = indexPath.row + 1;
        [cell.contentView addSubview:btnArrow];
        [cell.contentView bringSubviewToFront:btnArrow];
    }
}

但我无法btnArrowUTableView.

4

2 回答 2

1

您遇到崩溃的原因是没有任何东西保留您的CallBlock_Date_EditMode视图控制器。您将其视图作为子视图添加到您的单元格,但没有任何东西维护对视图控制器的引用,因此它被释放,然后,当按下应该将消息传递给视图控制器的按钮时,它被发送到释放对象,你会崩溃。

对此有两种可能的解决方案。首先,您可以将该视图控制器存储在您的一个属性中,以维护对它的引用,这样它就不会被释放。在大多数情况下,这可能不是您想要的。

相反,我建议不要将您的 CallBlock_Date_EditMode 设为 UIViewController,而是将其设为 UIView。您可能想知道“但是如何在没有 UIViewController 的情况下使用 xib?”。我会做类似以下的事情:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"CallBlock_Date_EditMode" owner:self options:nil] objectAtIndex:0];
        self.myEditButton = (UIButton *)[view viewWithTag:2];

        [self addSubview:view];
    }
    return self;
}

这将是您自定义 UIView 中的代码,该代码将加载到 xib 文件中并将其添加为子视图。为了访问您的子视图,您必须在界面构建器中使用标签,因此您确实失去了绘制/连接 IBOutlets 的便利......但最终,它比分配/存储一堆不必要的 UIViewControllers 要好得多.

于 2013-08-02T18:01:28.270 回答
1

如果我对您的理解正确,并且您想模仿 Apple 预装的闹钟功能,那么您的解决方案比创建自定义视图要简单得多。看起来他们所做的只是将开关设置为隐藏并在单元格中添加一个披露指示器。这就是我会做的...

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
      static NSString *CellIdentifier = @"Cell";
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

      bool hide = (tableView.editingStyle == UITableViewCellEditingStyleDelete); // set to true or false depending on if the table is in editing mode

      for (UIView *sv in [cell subviews] ) { 
           if([sv isKindOfClass:[UISwitch class]]) { // find the on-off switch
                [sv setHidden:hide]; // hide the switch depending on the t/f value of hide
                break;
           }
      }
      if(hide) { // adds the arrow like in apple's alarm clock table if the cell is in edit mode
           [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
      }
      else {
           [cell setAccessoryType:UITableViewCellAccessoryNone];
      }

 return cell;
 }
于 2013-08-02T18:22:02.237 回答