添加xib作为视图以在编辑模式下覆盖自定义UITableViewCell

时间:2013-08-02 17:29:46

标签: ios objective-c uiview uitableview

我正在尝试使用苹果的闹钟,当点按编辑按钮时,自定义视图会覆盖自定义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];
    }
}

但我无法在btnArrow上显示UTableView

2 个答案:

答案 0 :(得分: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要好得多

答案 1 :(得分:1)

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

 - (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;
 }