3

我正在尝试构建一个包含多个子视图的自定义 UITableCellView 但现在我只在其中两个(最大的)苦苦挣扎:一个 UIImageView (我不介意使用 UIWebView 代替,因为图像来自internet) 和一个 UITextView,它应该立即呈现所有文本而无需滚动。在这种情况下,我开始使用 XIB 文件和子类 UITableCellView (Autolayout disable) 构建自定义单元格:

在此处输入图像描述

我在自定义类中添加了两个新属性(IBOutlet)(非常简单):

@interface NewsFeedPostCell : UITableViewCell<UITextViewDelegate>
{
    UIImageView *picView;
    UITextView *postContent;
}

@property IBOutlet UIImageView *picView;
@property IBOutlet UITextView *postContent;

@end

之后我使用它们来填充数据(我从 iTunes 中获取一些返回漂亮 JSON @“ http://itunes.apple.com/search?term=ice%20age&country=us&entity=movie ”的东西)。目前,我专注于正确显示数据,而没有获得每个单元格的确切大小(除了不同的文本大小),但我有很多问题:内容没有正确显示,因为文本没有全部显示,首先行不显示图像等。我在stackoverflow上阅读了很多,但我开始对人们解决它的许多不同方式感到痛苦,因为我也测试过只使用代码来获取它并且我有类似的东西甚至更糟。

我的主要问题/抱怨是​​什么可能是构建具有不同高度和子视图的自定义单元格的复杂表格的最佳方法,以及如何计算尺寸,或者比这更好,何时何地(在代码中)因为heightForRowAtIndexPath之前被调用我已经下载了图像以获取它们的大小。布局、重绘和“尺寸拟合”有很多属性,但其中任何一个似乎都没有像我想象的那样工作。我觉得我太远了,不知道 iOS 应用程序中的布局是如何工作的,而且在我看来 UI 元素根本没有灵活性:(

这是使用的源代码(顺便说一下,我使用 AFNetworking 库来获取图像并将它们加载到 UIImageView 中):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"PostCell";
     NewsFeedPostCell *cell;

    NSDictionary *post = [self.posts objectAtIndex:indexPath.row];
    NSString *postText = [post objectForKey:@"longDescription"];

    cell= (NewsFeedPostCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"NewsFeedCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

 CGRect picFrame = cell.picView.frame;
    picFrame = CGRectMake(100, 0, 300, 100);
    [cell.picView setFrame:picFrame];
    [cell.picView  setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[post objectForKey:@"artworkUrl100"]]]
                        placeholderImage:nil
                                 success:^(NSURLRequest *request , NSHTTPURLResponse *response , UIImage *image ){
                                     NSLog(@"Loaded successfully: %d", [response statusCode]);
                                     [cell.picView setImage:image];
                                     [cell.picView sizeToFit];

                                 }
                                 failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
                                     NSLog(@"failed loading: %@", error);
                                 }
     ];

CGSize stringSize = [self calculateTextHeight:postText];

    CGRect postFrame = cell.postContent.frame;
    postFrame = CGRectMake(10, 100, 300, stringSize.height);
    cell.postContent.frame = postFrame;

    cell.postContent.autoresizingMask = UIViewAutoresizingFlexibleHeight;

    cell.postContent.font = [UIFont systemFontOfSize:POST_CONTENT_FONT_SIZE];
    cell.postContent.text= postText;

    [cell.postContent setContentInset:UIEdgeInsetsZero];

    [cell.postContent sizeThatFits:cell.postContent.contentSize];


    return cell;
}

查看截图中的问题(我正在使用模拟 3.5" 视网膜设备的 iOS 模拟器并用作构建应用程序 iOS SDK 6.1 的目标)

第一行(图像在顶栏下方;您必须滚动才能看到它) 这是第一行

另一行没有正确显示文本,我必须向下/向上滚动才能得到它: 在此处输入图像描述

在此处输入图像描述

并且不可能完成最后一行文本: 在此处输入图像描述

4

2 回答 2

2

制作具有不同高度的自定义单元格的最佳方法是:

为单元格制作一个 NSMutableArray:

@property (nonatomic,retain)NSMutableArray* cellsArray;

然后在米:

调用的第一个方法是

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

在这里制作你的手机:

        -(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
            if (!self.cellsArray) {

                self.cellsArray = [[NSMutableArray alloc]init];

            }

            ListCell* cell = [[ListCell alloc] initWithFrame:CGRectMake(0, 0,, 50)];


           // IMPLEMENT your custom cell here, with custom data, with custom,different height:

           // after add this cell to your array:
            [self.cellsArray addObject:cell];

           // IMPORTANT STEP:  set your cell height for the new height:

            cell.frame = CGRectMake(cell.frame.origin.x, cell.frame.origin.y, 303, yourLastItemInCell.frame.origin.y + yourLastItemInCell.frame.size.height);


            return cell.frame.size.height;
        }

在您获得具有不同高度的自定义单元格后:

#pragma mark - conform to delegates

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

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

    return 10;
}

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


    return self.cellsArray[indexPath.row];

}

我希望它有帮助!

于 2013-09-09T14:56:45.840 回答
0

谢谢大家。我尝试了您的解决方案,它们有效,但不完全。高度问题几乎解决了,但我遇到了单元格可视化问题,因为当它们稍长一点时,它们不会完全显示(图像既不是文本)。屏幕截图显示第一行和第二行。您可以看到,直到您向下滚动一点,第二行才可见,为了看到它,您应该向下滚动直到图像仅部分显示。这并不像我一开始想的那么容易。感谢您的意见和帮助。

在此处输入图像描述 在此处输入图像描述

谈到代码,我使用了 incmiko 的解决方案,但我仍然在下载图像时遇到问题,因为我应该异步执行此操作,之后必须重新绘制表视图以适应图像大小,但我不知道该怎么做。

自定义单元格:

@interface NewsFeedCell : UITableViewCell<UITextViewDelegate>
{
    UIImageView *picView;
    UITextView *postContent;
    float cellHeight;
}

@property  (nonatomic, retain) UIImageView *picView;
@property (nonatomic, retain) UITextView *postContent;
@property  (nonatomic) float cellHeight;

//-(id)initWithImageUrlString:(NSString *)imgUrl AndText:(NSString *)postText;
-(void)setPostImage:(NSString *)imgUrl;
-(void) setPostContenText:(NSString *)postText;
-(void) setcontentHeight;
-(float) getCellHeight;

@end

自定义单元格仅使用 TextView 初始化,因为未来的某些内容将没有任何图像(我知道在计算高度和内容视图大小时我必须注意这一点)。

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        [self setFrame:CGRectMake(CELL_LEFT_MARGIN, 0, CELL_TOTAL_WIDTH, 50)];


        postContent = [[UITextView alloc] initWithFrame:CGRectMake(CELL_LEFT_MARGIN, 0, CELL_TOTAL_WIDTH, 100)];
        [self.contentView addSubview:postContent];
    }
    return self;
}

我正在使用 AFNetworking 下载图像:

-(void)setPostImage:(NSString *)imgUrl
{
    picView =[[UIImageView alloc] initWithFrame:CGRectMake(0,0, 50, 50)];
    [picView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imgUrl]] placeholderImage:nil success:^(NSURLRequest *request , NSHTTPURLResponse *response , UIImage *pic )
     {
        //NSLog(@"Loaded successfully: %d", [response statusCode]);

         [picView setImage:pic];
         [self.contentView addSubview:picView];

         CGRect frame = CGRectMake((self.bounds.size.width/2-pic.size.width/2), 0, pic.size.width, pic.size.height);

         [picView setFrame:frame];

         frame = self.contentView.frame;
         frame.size.height = picView.frame.size.height;
         self.contentView.frame = frame;


    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
        NSLog(@"failed loading: %@", error);
    }
    ];


}

-(void)setPostContenText:(NSString *)postText
{
    CGSize stringSize = [self calculateTextHeight:postText];

    CGRect frame = postContent.frame;
    frame = CGRectMake(CELL_LEFT_MARGIN, picView.frame.origin.y+picView.frame.size.height, CELL_TOTAL_WIDTH, stringSize.height);
    postContent.frame = frame;
    postContent.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    postContent.font = [UIFont systemFontOfSize:POST_CONTENT_FONT_SIZE];
    postContent.text= postText;
    postContent.textColor=[UIColor blackColor];
    [postContent setContentInset:UIEdgeInsetsZero];
    [postContent setBackgroundColor:[UIColor whiteColor]];
    [postContent setEditable:NO];

    frame.size.height = stringSize.height + 5.0f;


}

-(void) setcontentHeight
{
    if(self)
    {
    CGRect frame = self.contentView.frame;
    frame = self.contentView.frame;
    frame.size.height = postContent.frame.size.height + picView.frame.size.height;
    self.contentView.frame = frame;
    self.cellHeight = self.contentView.frame.size.height + 10;

    NSLog(@"picView height: %f", picView.frame.size.height);
    NSLog(@"textview height: %f", postContent.frame.size.height);
    }
    else
        self.cellHeight = 44.0f;

}

和调用自定义单元格的控制器:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (self.cellsArray && self.cellsArray.count) {
        return self.cellsArray.count;
    } else {
        return 0;
    }
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [self.cellsArray[indexPath.row] getCellHeight];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   return self.cellsArray[indexPath.row];
}

#pragma mark -
-(void)createCellArray
{
    static NSString *simpleTableIdentifier = @"PostCell";
    if (!self.cellsArray) {
        self.cellsArray = [[NSMutableArray alloc]init];
    }

    for(NSDictionary *post in posts)
    {
        NSString *postText = [post objectForKey:@"longDescription"];//[posts objectAtIndex:indexPath.row];
        NewsFeedCell *cell= [[NewsFeedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        if(cell)
        {
            [cell setPostImage:[post objectForKey:@"artworkUrl100"]];
            [cell setPostContenText:postText];
            [cell setcontentHeight];            
            [cellsArray addObject:cell];
        }

    }
}
于 2013-09-11T07:55:32.933 回答