单元格子视图上的 UIButton 问题

Posted

技术标签:

【中文标题】单元格子视图上的 UIButton 问题【英文标题】:Problem with UIButton on subview of a cell 【发布时间】:2010-09-27 16:44:10 【问题描述】:

好的,在我解释问题之前,先简要介绍一下我的应用程序。 我的应用程序有两个视图,分别是自定义 TableViewCell、一个前视图和一个后视图(一旦你在单元格上滑动手指就会显示出来,就像 twitter 应用程序一样)。

任何人,我想在后视图上有一些按钮。我在 cellForRowAtIndexPath 方法中做到了这一点

您将在这里看到的第一个是我如何为单元格分配标签。您将看到的第二件事是按钮。它工作正常。

UILabel *nextArtist = [UILabel alloc];
        nextArtist.text = @"Rihanna";
        nextArtist.tag = 4;
        [cell setNextArtist:nextArtist];

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(6 ,31, 110, 20);
        [button setImage:[UIImage imageNamed:@"radionorge.png"] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(touched:) forControlEvents:UIControlEventTouchUpInside];



        [cell.backView addSubview:button];

但是,问题出现在下一个方法中。

-(void)touched:(id)sender 

    // Here i want to get the UILabels for each cell. Such as nextArtist.
    if ([sender isKindOfClass:[UIButton class]]) 
        UIButton *button = (UIButton *)sender;
        UIView *contentView = button.superview;
        UIView *viewWithTag4 = [contentView viewWithTag:4];
        if ([viewWithTag1 isKindOfClass:[UILabel class]]) 
            UILabel *titleLabel = (UILabel *)viewWithTag4;
            NSLog(@"Label: ",titleLabel.text);
        

    

所以,我意识到我不能只去按钮的超级视图并在那里找到我的标签,因为它们在另一个子视图中。我已经扫描了所有视图,但仍然找不到标签。

我对此很陌生,TableView-cell 的子类化是我从发布代码的人那里实现的。

但是,我的假设是我的视图中没有 UILabel,因为我没有将它们添加为视图,只是使用 drawTextInRect 函数绘制它们。

[nextArtist drawTextInRect:CGRectMake(boundsX+200 ,46, 110, 15)];

我尝试将它们添加为子视图,但没有成功。谁能帮帮我?

// 你可能需要更多的代码来解决这个难题(这是制作单元格视图的地方)

@implementation RadioTableCellView
- (void)drawRect:(CGRect)rect 

    if (!self.hidden)
        [(RadioTableCell *)[self superview] drawContentView:rect];
    
    else
    
        [super drawRect:rect];
    

@end

@implementation RadioTableCellBackView
- (void)drawRect:(CGRect)rect 

    if (!self.hidden)
        [(RadioTableCell *)[self superview] drawBackView:rect];
    
    else
    
        [super drawRect:rect];
    


@end

@interface RadioTableCell (Private)
- (CAAnimationGroup *)bounceAnimationWithHideDuration:(CGFloat)hideDuration initialXOrigin:(CGFloat)originalX;
@end

@implementation RadioTableCell
@synthesize contentView;
@synthesize backView;
@synthesize contentViewMoving;
@synthesize selected;
@synthesize shouldSupportSwiping;
@synthesize shouldBounce;

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

    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) 

        [self setBackgroundColor:[UIColor clearColor]];

        RadioTableCellView * aView = [[RadioTableCellView alloc] initWithFrame:CGRectZero];
        [aView setClipsToBounds:YES];
        [aView setOpaque:YES];
        [aView setBackgroundColor:[UIColor clearColor]];
        [self setContentView:aView];
        [aView release];

        RadioTableCellBackView * anotherView = [[RadioTableCellBackView alloc] initWithFrame:CGRectZero];
        [anotherView setOpaque:YES];
        [anotherView setClipsToBounds:YES];
        [anotherView setHidden:YES];
        [anotherView setBackgroundColor:[UIColor clearColor]];
        [self setBackView:anotherView];
        [anotherView release];

        // Backview must be added first!
        // DO NOT USE sendSubviewToBack:

        [self addSubview:backView];
        [self addSubview:contentView];

        [self setContentViewMoving:NO];
        [self setSelected:NO];
        [self setShouldSupportSwiping:YES];
        [self setShouldBounce:YES];
        [self hideBackView];
    

    return self;

请帮助我,或者至少给我指出一两个方向!

////////////////////// 更新了一些新代码: 这是在我的 RadioCustomCell 中,一个 UIView 子类。在这里绘制 UILabel

#import "RadioCustomCell.h"

@implementation RadioCustomCell
@synthesize nowTitle,nowArtist,nextTitle,nextArtist,ChannelImage;

// Setting the variables

- (void)setNowTitle:(UILabel *)aLabel 

    if (aLabel != nowTitle)
        [nowTitle release];
        nowTitle = [aLabel retain];
        [self setNeedsDisplay];
    


- (void)setNowArtist:(UILabel *)aLabel 

    if (aLabel != nowArtist)
        [nowArtist release];
        nowArtist = [aLabel retain];
        [self setNeedsDisplay];
    

- (void)setNextTitle:(UILabel *)aLabel 

    if (aLabel != nextTitle)
        [nextTitle release];
        nextTitle = [aLabel retain];
        [self setNeedsDisplay];
    

- (void)setNextArtist:(UILabel *)aLabel 

    if (aLabel != nextArtist)
        [nextArtist release];
        nextArtist = [aLabel retain];
        [self setNeedsDisplay];
    


- (void)setChannelImage:(UIImage *)aImage 

    if (aImage != ChannelImage)
        [ChannelImage release];
        ChannelImage = [aImage retain];
        [self setNeedsDisplay];
    


- (void)drawContentView:(CGRect)rect 

    CGContextRef context = UIGraphicsGetCurrentContext();

    //UIColor * backgroundColour = [UIColor whiteColor];

    UIColor *backgroundColour = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"CellBackground.png"]];

    [backgroundColour set];
    CGContextFillRect(context, rect);

    CGRect contentRect = self.contentView.bounds;
    CGFloat boundsX = contentRect.origin.x;

    [ChannelImage drawInRect:CGRectMake(boundsX+120 ,25, 75, 35)];

    nowTitle.enabled = YES;
    nowTitle.textAlignment = UITextAlignmentCenter;
    nowTitle.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size: 14.0];
    nowTitle.textColor = [UIColor blackColor];
    nowTitle.backgroundColor = [UIColor clearColor];
    //[nowTitle drawTextInRect:CGRectMake(boundsX+6 ,31, 110, 20)];

    // Trying to add a subview instead of drawing the text
    nowTitle.frame = CGRectMake(boundsX+6 ,31, 110, 20);
    [self addSubview:nowTitle];
    // I have also tried adding it to super, no effect.

    nowArtist.enabled = YES;
    nowArtist.textAlignment = UITextAlignmentCenter;
    nowArtist.font = [UIFont fontWithName:@"HelveticaNeue" size: 10.0];
    nowArtist.textColor = [UIColor blackColor];
    nowArtist.backgroundColor = [UIColor clearColor];
    [nowArtist drawTextInRect:CGRectMake(boundsX+6 ,46, 110, 15)];

    nextTitle.enabled = NO;
    nextTitle.textAlignment = UITextAlignmentCenter;
    nextTitle.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size: 12.0];
    [nextTitle drawTextInRect:CGRectMake(boundsX+200 ,31, 110, 20)];

    nextArtist.enabled = NO;
    nextArtist.textAlignment = UITextAlignmentCenter;
    nextArtist.font = [UIFont fontWithName:@"HelveticaNeue" size: 9.0];
    [nextArtist drawTextInRect:CGRectMake(boundsX+200 ,46, 110, 15)];



【问题讨论】:

RadioTableCellView 是 UITableViewCell 的子类吗?如果是这样的话,我想我有更好的方法。 不,它是 UIView 的子类,而 RadioTableCell 是 UITableViewCell 的子类。 【参考方案1】:

您只是忘记在您的第一行代码中初始化您的 UILabel。 :)

【讨论】:

【参考方案2】:

乍一看,我可以肯定,如果您绘制文本(并且文本不是标签),那么您的单元格中根本没有 UILabel 。你可以忽略这种方式。

所以,如果您没有UILabel,您如何获取文本。因为你的 contentView 确实是一个RadioTableCellView,那就不难了。在您的班级中,只需公开一个名为nextArtist 的属性。当您的按钮被点击时,查找contentView(通过调用一些超级视图),将其转换为RadioTableCellView,然后取出nextArtist

【讨论】:

我就是这么想的。我试过用 addSubview 替换 drawTextInRect,但没有效果。 你应该用 addSubview 发布代码,可能有问题 更新了代码。在 nowTitle 下看,我尝试在那里添加一个子视图。 你的表格单元格必须有一个名为 nextArtist 的 UILabel 属性,或者这一行 '[cell setNextArtist:nextArtist];'会呕吐。即使您不使用它们进行绘图,您的单元格也有与之关联的标签。 我不太明白你的意思,但是代码运行良好,文字显示也不错。问题是我无法指向标签。但如果你的意思是我需要为 nextArtist 等创建属性,我已经做到了。我的头文件:@property(nonatomic,retain)UILabel *nextArtist;【参考方案3】:

无需编写大量代码,这是我的最佳猜测。

您需要在 initWithStyle: 方法中为 aView 和 anotherView 分配标签。我假设你有几个常量:BACK_VIEW_TAGFRONT_VIEW_TAG

在您的touched: 方法中,向上遍历视图层次结构,直到找到您的 UITableViewCell。

UIView *currentView = button.superView;
while (![currentView isKindOfClass:UITableViewCell] && currentView != nil) 
    currentView = currentView.parent;

使用标签从表格单元格的 contentView 中获取前视图和后视图(或任何你想要的)。

if (currentView != nil) 
    UITableViewCell *cellView = (UITableViewCell *)currentView)
    UIView *cellContentView = cellView.contentView;
    UIView *backView = [cellContentView viewWithTag:BACK_VIEW_TAG];
    UIView *frontView = [cellContentView viewWithTag:FRONT_VIEW_TAG];

    // Get other views from frontView and backView using viewWithTag:.

请注意,您应该将视图添加到 UITableViewCell 子类的 contentView,而不是直接添加到 UITableViewCell。有关详细信息,请参阅Programmatically Adding Subviews to a Cell’s Content View。

【讨论】:

说了这么多,如果你只想要文本而不是实际控制,vodkhang 的方法是要走的路。

以上是关于单元格子视图上的 UIButton 问题的主要内容,如果未能解决你的问题,请参考以下文章

单元格子视图约束在 CellForRowAtIndex 中以编程方式更改

UITableview 单元格子视图的高度比单元格大

UICollectionView 单元格子视图不调整大小

iPhone:如何从视图控制器中获取自定义单元格的按钮操作?

阅读更多 UIButton 上的单元格高度增加问题

在自定义表格视图单元格中设置 UIButton 的高度