如何在编辑模式下将子视图添加到 UITableViewCell 并调整其大小?

Posted

技术标签:

【中文标题】如何在编辑模式下将子视图添加到 UITableViewCell 并调整其大小?【英文标题】:How to add a subview to a UITableViewCell and resize it while in editing mode? 【发布时间】:2011-05-26 11:46:02 【问题描述】:

编辑:我开始赏金,因为我正在寻找具有UITableViewCell 子类 的“更清洁”解决方案,而不是搞乱UITableView 代表和数据源。理想情况下,我想看看如何处理UISlider 事件。谢谢!

我使用的是组样式的UITableView,并且我有几个看起来像这样的单元格:

现在,当我处于编辑模式时,我想要一个 UISlider 来设置正确的 UILabel 的值,因此结果如下所示:

有人能指出我正确的方向吗?我什至不确定是否应该通过子类化UITableViewCell 或在 IB 中做到这一点。代码 sn-ps 将不胜感激:)

【问题讨论】:

你能把你在cellForRowAtIndexPath中所做的代码贴出来 我还没有做任何事情,但是您对 cellForRowAtIndexPath 有什么想法? 好主意!祝你的项目好运! 【参考方案1】:

作为赏金的傻瓜,我坐下来进行了一些实验。这是我发现的最干净的解决方案:

您将创建一个自定义单元格类。正如我从您的帖子中读到的,您对此没有任何问题,我相信这确实是唯一的方法。

在头文件中:

@interface TableCellSlider : UITableViewCell 
    UISlider *cellSlider;

在主文件中:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
        cellSlider = [[UISlider alloc] initWithFrame:CGRectMake(200, 10, 100, 20)];
        [self addSubview:cellSlider];
        cellSlider.hidden = YES;
    

    return self;


- (void)didTransitionToState:(UITableViewCellStateMask)state
 
    if (self.editing) 
        cellSlider.hidden = NO;
     else 
        cellSlider.hidden = YES;
    


- (float)getValue 
    return cellSlider.value;

至于表格和单元格高度,将其添加到表格脚本中:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

    [self.tableView beginUpdates];
    [super setEditing:editing animated:YES];
    [self.tableView endUpdates];
    //[self.tableView reloadData];



    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
     
        if (self.editing) 
            return 50;
         else 
            return 30;
        
    

这应该可以解决问题。您可以在单元格上使用 getValue,因此您不必合成滑块,并且无论出于何种原因单元格变为可编辑,它们都会隐藏/重新出现。

祝你的项目好运:]

【讨论】:

[self.tableView reloadData]; 调用不会中断setEditing 方法上的动画吗? 你说得对,marza,我没想到。我更改了代码以使用更新系统,幸运的是,它还重新加载了单元格高度。 :] 问题已修复 即使问题不是我的,我也喜欢它,我也喜欢你的解决方案(现在)。 太好了,这就是我要找的!实际上我得到了它的工作,但现在我尝试为 UISlider 设置动画,以便它与单元格一起淡入/淡出。我添加了一个 [UIView beginAnimations] 块,但不幸的是它在单元格转换完成后被调用。有什么想法吗?? 您可以将其帧 x 更改为正确的位置或 tableview.frame.width,而不是在 didTransitionToState 中隐藏/显示它。这将在不应该显示时将其滑出屏幕,无论旋转或表格大小。【参考方案2】:

首先,创建一个新的基于导航的项目,然后创建一个新的类文件,分别命名为CustomCell.hCustomCell.m

将此代码复制并粘贴到您的 RootViewController.m 文件中:

#import "RootViewController.h"
#import "CustomCell.h"

@implementation RootViewController

- (void)viewDidLoad

    [super viewDidLoad];
    self.navigationItem.rightBarButtonItem=self.editButtonItem;


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 2;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return 1;


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

    static NSString *CellIdentifier = @"Cell";

    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
    
    cell.mainLabel.text=@"ValueName";

    return cell;


- (void)setEditing:(BOOL)editing animated:(BOOL)animated

    [super setEditing:editing animated:animated];
    [self.tableView beginUpdates];
    [self.tableView endUpdates];


- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

    if(tableView.editing)
        return 70;
    
    return 44;


- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath

    return NO;


- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

    return UITableViewCellEditingStyleNone;


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    return;


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];


- (void)viewDidUnload

    [super viewDidUnload];


- (void)dealloc

    [super dealloc];


@end

CustomCell.h:

#import <UIKit/UIKit.h>


@interface CustomCell : UITableViewCell 



@property (nonatomic, retain) UILabel *mainLabel;
@property (nonatomic, retain) UILabel *detailLabel;
@property (nonatomic, retain) UISlider *slider;

@end

CustomCell.m:

#import "CustomCell.h"

@implementation CustomCell
@synthesize mainLabel, detailLabel, slider;

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

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
        slider = [[UISlider alloc] initWithFrame:CGRectMake(10, 12, 280, 0)];
        slider.alpha = 0;
        slider.maximumValue = 30;
        slider.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
        [self.contentView addSubview:slider];
        [slider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventTouchDragInside];
        [slider release];

        mainLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 12, 150, 20)];
        mainLabel.highlightedTextColor = [UIColor whiteColor];
        mainLabel.backgroundColor = [UIColor clearColor];
        [self.contentView addSubview:mainLabel];
        [mainLabel release];

        detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.bounds.size.width-180, 12, 150, 20)];
        detailLabel.textAlignment=UITextAlignmentRight;
        detailLabel.text = [NSString stringWithFormat:@"%i", lroundf(slider.value)];
        detailLabel.highlightedTextColor = [UIColor whiteColor];
        detailLabel.backgroundColor = [UIColor clearColor];
        [self.contentView addSubview:detailLabel];
        [detailLabel release];
    
    return self;


- (void)setEditing:(BOOL)editing animated:(BOOL)animated

    [super setEditing:editing animated:animated];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationBeginsFromCurrentState:YES];

    if(editing)
        slider.alpha = 1;
        slider.userInteractionEnabled=YES;
    else
        slider.alpha = 0;
        slider.userInteractionEnabled=NO;
    

    [UIView commitAnimations];


-(IBAction) sliderChanged:(id) sender
    detailLabel.text=[NSString stringWithFormat:@"%i", lroundf(slider.value)];


- (void)dealloc

    [super dealloc];


@end

编译并运行,您就拥有了您想要的完美版本的控件。我什至实现了像黄油一样流畅的动画。玩得开心!

编辑: 如果确实要使用编辑控件,则不能实现以下方法,必须调整标签和滑块的框架。

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

    return UITableViewCellEditingStyleNone;

【讨论】:

非常感谢您的回答-效果很好!我只需要添加 -(BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath return NO; 因此,如果您愿意,请编辑您的答案以供将来参考。【参考方案3】:

您需要在名为的 delgate 方法中重新配置您的单元格

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath

当用户交换单元格以进行删除时调用此方法

在哪里可以通过UITableView的方法找到cell

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

然后重新配置它

有关更多信息,请参阅开发人员文档

【讨论】:

【参考方案4】:

据我所知,您可以在编辑开始时添加滑块。我的意思是在下面的方法中。

- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath*)indexPath

    /*  Add your slider.  */

谢谢。

【讨论】:

【参考方案5】:

我只是盲目拍摄,因为我没有自己实现它,但是,用新尺寸重新加载表格可能会有所帮助,您可以在编辑模式下覆盖,以下方法..

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
 
    return (int)yourHeight;

【讨论】:

我也考虑过这一点,我将从实现类似的东西开始,但我希望(并且觉得)应该有更好的解决方案.. 重新加载表格将松开红色的删除按钮...通过这种方法,您将永远无法编辑单元格,因为每次您尝试删除表格重新加载时,它都会设置其表格视图集其编辑属性为 NO @Irene:是的,我也和你想的一样,希望最好:)

以上是关于如何在编辑模式下将子视图添加到 UITableViewCell 并调整其大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不从当前活动选项卡中获取焦点的情况下将子窗口添加到 QMdiArea(设置为 TAB 模式)?

iphone - 将子视图添加到窗口后无法推送模态视图?

如何将子视图添加到 UITableViewCell

如何将子视图添加到自定义 UICollectionViewCell

如何将子视图添加到情节提要中的自定义 UITableViewCell

如何使用自动布局(约束)将子视图添加到 UIPageViewController?