将子视图添加到显示奇怪行为的单元格视图

时间:2013-01-03 08:27:41

标签: iphone objective-c cocoa-touch

我正在尝试将单元格添加到tableView

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *MyIdentifier = @"MyIdentifier";
        UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
        cell.accessoryType = UITableViewCellAccessoryNone;
        [cell setSelectionStyle:UITableViewCellEditingStyleNone];
        // Set up the cell

        cell.backgroundColor = [UIColor clearColor];
        UIButton *buyBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImageView *img;
        UILabel *lbl;
        UIImageView *backImage;
        UILabel *textLabel;
        UILabel *detailTextLabel;

        NSInteger val = [indexPath row] * 3;

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        {
            //*buyBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, w, h)];
            [buyBtn setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];

            //*img = [[UIImageView alloc] initWithFrame:CGRectMake(x, y, w, h)];
            [img setImage:[UIImage imageNamed:@""]];
            //*lbl = [[UILabel alloc] initWithFrame:CGRectMake(x,y,w,h)];
        }
        else
        {
            backImage =  [[UIImageView alloc] initWithFrame:CGRectMake(2, 4, 316, 62)];
            [buyBtn setFrame:CGRectMake(257, 100, 57, 24)];
            img = [[UIImageView alloc] initWithFrame:CGRectMake(257, 75, 57, 24)];

            lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 57, 24)];
            textLabel = [[UILabel alloc] initWithFrame:CGRectMake(4, 4, 230, 25)];
            detailTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(4, 25, 230, 30)];

            backImage.image = [UIImage imageNamed:@"shop-bg.png"];
            [buyBtn setImage:[UIImage imageNamed:@"buy_button"] forState:UIControlStateNormal];
            [img setImage:[UIImage imageNamed:@"price_button.png"]];

            lbl.center = img.center;
            lbl.textAlignment =  UITextAlignmentCenter;
            lbl.text = [self.original_List objectAtIndex:val+2];
            lbl.backgroundColor = [UIColor clearColor];

            textLabel.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:14];
            textLabel.backgroundColor = [UIColor clearColor];
            textLabel.text = [self.original_List objectAtIndex:val];

            detailTextLabel.text = [self.original_List objectAtIndex:val+1];
            detailTextLabel.backgroundColor = [UIColor clearColor];
            detailTextLabel.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:10];
            textLabel.textColor = [UIColor blackColor];
            detailTextLabel.textColor = [UIColor whiteColor];
            detailTextLabel.numberOfLines = 2;
        }

        [buyBtn setTag:[indexPath row]];
        [buyBtn addTarget:self action:@selector(buyBtnPressed:) forControlEvents:UIControlEventTouchDown];
        [cell addSubview:backImage];
        [cell addSubview:detailTextLabel];
        [cell addSubview:textLabel];
        [cell addSubview:buyBtn];
        [cell addSubview:img];
        [cell addSubview:lbl];

        return cell;
    }

从图中可以看出,第一个单元格不包含添加的图像,标签和按钮,但是如果滚动其他单元格,那些丢失视图的人会变得透明,而那些在视野中的人是可以的。

为什么我的三个子视图没有从第一个单元格添加,我的textLabel和detailTextLabel会按原样添加。

enter image description here

4 个答案:

答案 0 :(得分:1)

首先,您不要将单元格出列,并始终创建一个新单元而不重复使用。尝试添加这样的东西(不确定你是否需要自动释放,取决于你使用ARC的天气与否):

RecentsTableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
        cell = [[[RecentsTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                            reuseIdentifier:cellIdentifier] autorelease];
}

其次,如果你没有使用ARC(自动引用计数),那么你在这里有很多丢失的引用。

[[class alloc] init]添加ref和addSubview也添加了ref。我想知道xcode“analyze”build对此有何看法。

第三,imho你添加到单元格的所有标签也需要它们的“框架”属性来设置,而不仅仅是行数等。

答案 1 :(得分:0)

这是我如何做到的例子。我创建的cell类派生了你需要的东西(在我的例子中是CopyableCell)。

这是* .h文件。

#import <UIKit/UIKit.h>
#import "CopyableCell.h"

@interface RecentsTableViewCell : CopyableCell

@property (readonly, retain) UILabel *titleLabel;
@property (readonly, retain) UILabel *detailsLabel;
@property (readonly, retain) UILabel *subdetailsLabel;
@property (readonly, retain) UILabel *subtitleLabel;

@end

这是* .m文件。

#import "RecentsTableViewCell.h"

@interface RecentsTableViewCell ()

// Redeclare property as readwrite
@property (readwrite, retain) UILabel *titleLabel;
@property (readwrite, retain) UILabel *subtitleLabel;
@property (readwrite, retain) UILabel *detailsLabel;
@property (readwrite, retain) UILabel *subdetailsLabel;

@end

@implementation RecentsTableViewCell

@synthesize titleLabel;
@synthesize subtitleLabel;
@synthesize detailsLabel;
@synthesize subdetailsLabel;

- (void) layoutSubviews
{
        int leftMargin = 30;
        int rightMargin = 6;

        [super layoutSubviews];

        CGRect cellRect = self.contentView.frame;
        int width = cellRect.size.width - (leftMargin + rightMargin);

        CGSize constraintSize = CGSizeMake(300, MAXFLOAT);
        CGSize titleSize = [titleLabel.text sizeWithFont:titleLabel.font
                                       constrainedToSize:constraintSize
                                 lineBreakMode:UILineBreakModeTailTruncation];
        CGSize detailsSize = [detailsLabel.text sizeWithFont:detailsLabel.font
                                           constrainedToSize:constraintSize
                                     lineBreakMode:UILineBreakModeTailTruncation];

        if (titleSize.width > titleLabel.frame.size.width ||
            detailsSize.width > detailsLabel.frame.size.width) {
                CGRect detailsFrame = detailsLabel.frame;
                detailsFrame.size.width = detailsSize.width;
                detailsFrame.origin.x = cellRect.size.width -
                        (detailsSize.width + subdetailsLabel.frame.size.width + rightMargin);

                CGRect titleFrame = titleLabel.frame;
                titleFrame.size.width = width - detailsSize.width - subdetailsLabel.frame.size.width - 5;

                titleLabel.frame = titleFrame;
                detailsLabel.frame = detailsFrame;
        }
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
                CGRect cellRect = self.contentView.frame;
                cellRect.size.height = 61;
                self.contentView.frame = cellRect;

                int leftMargin = 30;
                int rightMargin = 6;
                int x = cellRect.origin.x + leftMargin;
                int y = cellRect.origin.y;
                int width = cellRect.size.width - (leftMargin + rightMargin);
                int height = cellRect.size.height;

                int titleWidth = width * 0.75;
                int alldetailsWidth = width - titleWidth;
                int detailsWidth = alldetailsWidth * 0.65;
                int subdetailsWidth = alldetailsWidth - detailsWidth;

                int titleHeight = height * 0.38;
                int subtitleHeight = height - titleHeight;

                self.titleLabel = [[[UILabel alloc]
                                    initWithFrame:CGRectMake(x, y, titleWidth, titleHeight)] autorelease];
                self.titleLabel.font = [UIFont boldSystemFontOfSize:18.0f];
                self.titleLabel.highlightedTextColor = self.textLabel.highlightedTextColor;
                self.titleLabel.textAlignment = UITextAlignmentLeft;
                self.titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth |
                        UIViewAutoresizingFlexibleBottomMargin;
                [self.contentView addSubview:titleLabel];

                self.detailsLabel = [[[UILabel alloc]
                                 initWithFrame:CGRectMake(cellRect.size.width -
                                                          (detailsWidth + subdetailsWidth + rightMargin),
                                                          y + 4, detailsWidth, titleHeight - 4)] autorelease];
                self.detailsLabel.font = [UIFont boldSystemFontOfSize:13.0f];
                self.detailsLabel.textColor = [UIColor colorWithRed:0.12 green:0.439 blue:0.847 alpha:1];
                self.detailsLabel.textAlignment = UITextAlignmentRight;
                self.detailsLabel.highlightedTextColor = self.textLabel.highlightedTextColor;
                self.detailsLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
                        UIViewAutoresizingFlexibleHeight;
                [self.contentView addSubview:detailsLabel];

                self.subdetailsLabel = [[[UILabel alloc]
                                initWithFrame:CGRectMake(cellRect.size.width - (subdetailsWidth + rightMargin),
                                                         y + 6, subdetailsWidth, titleHeight - 6)] autorelease];
                self.subdetailsLabel.font = [UIFont systemFontOfSize:11.0f];
                self.subdetailsLabel.textColor = [UIColor colorWithRed:0.12 green:0.439 blue:0.847 alpha:1];
                self.subdetailsLabel.textAlignment = UITextAlignmentCenter;
                self.subdetailsLabel.highlightedTextColor = self.textLabel.highlightedTextColor;
                self.subdetailsLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
                        UIViewAutoresizingFlexibleHeight;
                [self.contentView addSubview:subdetailsLabel];

                self.subtitleLabel = [[[UILabel alloc]
                                  initWithFrame:CGRectMake(x, y + titleHeight, width, subtitleHeight - 2)] autorelease];
                self.subtitleLabel.highlightedTextColor = self.textLabel.highlightedTextColor;
                self.subtitleLabel.font = [UIFont systemFontOfSize:13.0f];
                self.subtitleLabel.textColor = [UIColor darkGrayColor];
                self.subtitleLabel.numberOfLines = 2;
                self.subtitleLabel.lineBreakMode = UILineBreakModeTailTruncation;
                self.subtitleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth |
                        UIViewAutoresizingFlexibleTopMargin;
                [self.contentView addSubview:subtitleLabel];

                self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
        return self;
}

- (id) init
{
        return [self initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RecentsCell"];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
        [super setSelected:selected animated:animated];
}

- (void) dealloc
{
        self.titleLabel = nil;
        self.subtitleLabel = nil;
        self.detailsLabel = nil;
        self.subdetailsLabel = nil;
        [super dealloc];
}

@end

请注意,我没有使用ARC,因此如果您使用此代码,请相应地进行修改。以下是我在表视图控制器中使用此类的方法。

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
        static NSString *cellIdentifier = @"TransactionCell";
        NSMutableArray *data = searching ? searchResult : dataSource;
        NSDictionary *object = [data objectAtIndex:[indexPath row]];

        RecentsTableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (cell == nil) {
                cell = [[[RecentsTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                                    reuseIdentifier:cellIdentifier] autorelease];
        }
        cell.selectionStyle = UITableViewCellSelectionStyleBlue;
        cell.indexPath = indexPath;
        cell.delegate = self;

        cell.titleLabel.text = @"Transaction title";
        if (pendingTransaction) {
                cell.titleLabel.textColor = [UIColor grayColor];
                cell.titleLabel.font = [UIFont systemFontOfSize:cell.titleLabel.font.pointSize];
        } else {
                if (!isGreen)
                        cell.titleLabel.textColor = [UIColor colorWithRed:0.733 green:0.098
                                                                     blue:0.098 alpha:1];
                else
                        cell.titleLabel.textColor = cell.textLabel.textColor;
                cell.titleLabel.font = [UIFont boldSystemFontOfSize:cell.titleLabel.font.pointSize];
        }
        cell.subtitleLabel.text = @"Transaction subtitle";
        cell.detailsLabel.text = @"Some details like location";
        cell.subdetailsLabel.text = @"200 USD";
        return cell;
}

这会产生与你在iphone通话应用程序中看到的非常类似的表格,即在单元格最右边位置的蓝色标题,副标题,子细节等等。

您可以在appstore中的Torchoo应用中看到它。它是免费使用的,您可以使用测试帐户登录并将其视为示例。

希望这有点帮助。

答案 2 :(得分:0)

您是否不断向单元格添加subView而不删除任何子视图? 添加subView 类似代码检查条件不完全我写的:

  if ([[cell.contentView subviews] count]==0) {
  [self.contentView addSubview:imageView];
 }

如果单元格内容视图不包含该视图,则添加它。

答案 3 :(得分:0)

以前的答案是正确的,尽管你可以修复更多。

只有在单元格未出列时才应调用添加子视图的代码部分。否则,您将添加相同按钮,视图等的多个实例。

[cell addSubview:backImage];
[cell addSubview:detailTextLabel];
[cell addSubview:textLabel];
[cell addSubview:buyBtn];
[cell addSubview:img];
[cell addSubview:lbl];

另外我想最好添加到cell.contentView而不是直接添加到单元格。所以看起来应该是这样的:

RecentsTableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
    cell = [[[RecentsTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                        reuseIdentifier:cellIdentifier] autorelease];

    /*Create your subviews here*/

    [cell.contentView addSubview:backImage];
    [cell.contentView addSubview:detailTextLabel];
    [cell.contentView addSubview:textLabel];
    [cell.contentView addSubview:buyBtn];
    [cell.contentView addSubview:img];
    [cell.contentView addSubview:lbl];
}

// Below just set properties of existing subviews of the cell: color, textColor, text etc.
// You need to retrieve them and one way is to assign them to properties in 
// RecentsTableViewCell or set the tag property of the subviews and retrieve
// them using e.g. [cell.contentView viewWithTag:kBuyButtonTag].
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    ...
}
else {
    ...
}