IOS,如何在包含不同子视图的UITableViewCell中设置自动布局

时间:2022-11-13 10:52:38

I have a layout issue, i have a UIView that contains an UIImageView and three other UILabels. The part that needs to set the layout dynamically is the main UIView thats added to the cell and a UILabel that will contain text of any length lets say for this example.

我有一个布局问题,我有一个包含UIImageView和其他三个UILabel的UIView。需要动态设置布局的部分是添加到单元格的主要UIView和包含任意长度文本的UILabel,例如。

What i have done i created a custom UITableViewCell and added the SubViews to the custom UITableViewCell, like here:

我做了什么,我创建了一个自定义UITableViewCell并将SubViews添加到自定义UITableViewCell,如下所示:

        -(void)setupView:(PostInfo*)postInfo{


            CGRect screenRect = [[UIScreen mainScreen] bounds];
            viewPostMessage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, screenRect.size.width - 20, 100)];
            viewPostMessage.backgroundColor = [UIColor colorWithRed:193.0f/255 green:193.0f/255 blue:193.0f/255 alpha:1.0f];
            viewPostMessage.layer.borderColor = [UIColor blackColor].CGColor;
            viewPostMessage.layer.borderWidth = 0.5f;


            if(postInfo.userImage.length > 0){
            userImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
            UIImage *imageUser =  [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:@"http://www.hugt.co.uk/userimage/%d/userImage.jpg", postInfo.userId]]]];
            userImage.image = imageUser;
            [viewPostMessage addSubview:userImage];
            }else{
            UIView *viewImage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
            viewImage.backgroundColor = [UIColor colorWithRed:132.0f/255 green:132.0f/255 blue:132.0f/255 alpha:1.0f];
            [viewPostMessage addSubview:viewImage];

            userImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
            UIImage *imageUser = [UIImage imageNamed:@"defaultuser.jpg"];
            userImage.image = imageUser;
            [viewImage addSubview:userImage];
            }

            labelUserName = [[UILabel alloc] initWithFrame:CGRectMake(50, 8, 200, 16)];
            labelUserName.textColor = [UIColor colorWithRed:56.0f/255 green:56.0f/255 blue:57.0f/255 alpha:1.0f];
            labelUserName.text = [NSString stringWithFormat:@"%@ %@ posted...", postInfo.firstName,postInfo.lastName];
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelUserName.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelUserName.userInteractionEnabled = YES;
            [viewPostMessage addSubview:labelUserName];

            labelCreated = [[UILabel alloc] initWithFrame:CGRectMake(50, 24, 200, 16)];
            labelCreated.textColor = [UIColor colorWithRed:86.0f/255 green:152.0f/255 blue:179.0f/255 alpha:1.0f];
            labelCreated.text = [NSDateFormatter localizedStringFromDate:postInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
            labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:@"AM" withString:@""];
            labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:@"PM" withString:@""];
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelCreated.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelCreated.userInteractionEnabled = YES;
            [viewPostMessage addSubview:labelCreated];

            labelMessage = [[UILabel alloc] initWithFrame:CGRectMake(50, 43, 210, 50)];
            labelMessage.textColor = [UIColor colorWithRed:141.0f/255 green:142.0f/255 blue:142.0f/255 alpha:1.0f];
            labelMessage.text = postInfo.message;
            labelMessage.numberOfLines = 3;
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelMessage.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelMessage.userInteractionEnabled = YES;
            [labelMessage sizeToFit];
            [viewPostMessage addSubview:labelMessage];

            [self.contentView addSubview:viewPostMessage];

        }

When i create this custom UITableViewCell i pass in an object that sets the text on the UILabels, like this:

当我创建这个自定义UITableViewCell时,我传入一个在UILabel上设置文本的对象,如下所示:

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


            if(tableViewThreads == tableView){
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

            if (cell == nil)
            {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
            }
            ThreadInfo *threadInfo = (ThreadInfo*)[self.threadsArray objectAtIndex:indexPath.row];
            [cell.contentView addSubview:[self setupThreadItem:threadInfo]];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            return cell;

            }
            if(tableViewPosts == tableView){
            PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

            if (cell == nil)
            {
                cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
            }

            PostInfo *postInfo = (PostInfo*)[self.postsArray objectAtIndex:indexPath.row];
            [cell setupView:postInfo];



            //[cell addSubview:[self setupPostItem:postInfo]];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            return cell;
            //[cell.contentView addSubview:[self setupThreadItem:threadInfo]];
            }

            return nil;
        }

I have searched the web and also here to find out how to Auto Layout the Subviews in the cell but can't seem to understand what needs to go next. I read that you need a Prototype Cell so i created a custom UITableViewCell and thats how far I've got.

我在网上搜索过,也在这里找到如何在单元格中自动布局子视图,但似乎无法理解下一步需要做什么。我读到你需要一个原型单元,所以我创建了一个自定义的UITableViewCell,这就是我有多远。

Any help would be appreciated, thanks.

任何帮助将不胜感激,谢谢。

1 个解决方案

#1


0  

So far i have got the cells to resize with Auto Layout but i have removed the UIView that sits inside the cell, so now i have three UILabels and an UIImageView which are the UIImageView (userImage), UILabel (labelUsername), UILabel (labelCreated) and UILabel (labelMessage). So the dimensions and coordinates are the same just that the UIView has been removed:

到目前为止,我已经使用自动布局调整了单元格,但是我已经删除了位于单元格内的UIView,所以现在我有三个UILabel和一个UIImageView,它们是UIImageView(userImage),UILabel(labelUsername),UILabel(labelCreated)和UILabel(labelMessage)。因此,尺寸和坐标与UIView被移除的相同:

First i set up NSLayoutContsraints in my Custom Cell, code bellow:

首先,我在自定义单元格中设置NSLayoutContsraints,代码如下:

Set numberOFLines = 0 and remove sizeToFit on the UILabel thats going to AutoLayout.

设置numberOFLines = 0并删除要转到AutoLayout的UILabel上的sizeToFit。

-(void)setupView:(PostInfo*)postInfo{


            CGRect screenRect = [[UIScreen mainScreen] bounds];
            viewPostMessage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, screenRect.size.width - 20, 100)];
            viewPostMessage.backgroundColor = [UIColor colorWithRed:193.0f/255 green:193.0f/255 blue:193.0f/255 alpha:1.0f];
            viewPostMessage.layer.borderColor = [UIColor blackColor].CGColor;
            viewPostMessage.layer.borderWidth = 0.5f;


            if(postInfo.userImage.length > 0){
            userImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
            UIImage *imageUser =  [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:@"http://www.hugt.co.uk/userimage/%d/userImage.jpg", postInfo.userId]]]];
            userImage.image = imageUser;
            [self.contentView addSubview:userImage];
            }else{
            UIView *viewImage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
            viewImage.backgroundColor = [UIColor colorWithRed:132.0f/255 green:132.0f/255 blue:132.0f/255 alpha:1.0f];
            [self.contentView addSubview:viewImage];

            userImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
            UIImage *imageUser = [UIImage imageNamed:@"defaultuser.jpg"];
            userImage.image = imageUser;
            [viewImage addSubview:userImage];
            }

            labelUserName = [[UILabel alloc] initWithFrame:CGRectMake(50, 8, 200, 16)];
            labelUserName.textColor = [UIColor colorWithRed:56.0f/255 green:56.0f/255 blue:57.0f/255 alpha:1.0f];
            labelUserName.text = [NSString stringWithFormat:@"%@ %@ posted...", postInfo.firstName,postInfo.lastName];
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelUserName.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelUserName.userInteractionEnabled = YES;
            [self.contentView addSubview:labelUserName];

            labelCreated = [[UILabel alloc] initWithFrame:CGRectMake(50, 24, 200, 16)];
            labelCreated.textColor = [UIColor colorWithRed:86.0f/255 green:152.0f/255 blue:179.0f/255 alpha:1.0f];
            labelCreated.text = [NSDateFormatter localizedStringFromDate:postInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
            labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:@"AM" withString:@""];
            labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:@"PM" withString:@""];
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelCreated.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelCreated.userInteractionEnabled = YES;
            [self.contentView addSubview:labelCreated];

            labelMessage = [[UILabel alloc] initWithFrame:CGRectMake(50, 43, 210, 50)];
            labelMessage.textColor = [UIColor colorWithRed:141.0f/255 green:142.0f/255 blue:142.0f/255 alpha:1.0f];
            labelMessage.text = postInfo.message;
            labelMessage.numberOfLines = 0;
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelMessage.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelMessage.userInteractionEnabled = YES;
            labelMessage.lineBreakMode = NSLineBreakByWordWrapping;
            //[labelMessage sizeToFit];
            [self.contentView addSubview:labelMessage];

            labelMessage.translatesAutoresizingMaskIntoConstraints = NO;

            [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[bodyLabel]-19-|" options:0 metrics:nil views:@{ @"bodyLabel": labelMessage }]];
            [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-43-[bodyLabel]-6-|" options:0 metrics:nil views:@{ @"bodyLabel": labelMessage }]];

            //[self.contentView addSubview:viewPostMessage];

        }

Then in my ViewController that contains the UITableVIew, i modified this bit of code:

然后在我的包含UITableVIew的ViewController中,我修改了这段代码:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
            static NSString *cellIdentifier = @"cell";
            if(tableViewThreads == tableView){

            return 122;

            }
            if(tableViewPosts == tableView){
            PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

            if (cell == nil)
            {
                cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
            }

            PostInfo *postInfo = (PostInfo*)[self.postsArray objectAtIndex:indexPath.row];
            [cell setupView:postInfo];

            [cell setNeedsLayout];
            [cell layoutIfNeeded];

            CGFloat h = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

            return h + 1;


            }
            return 0;
        }

The Cells do now resize and the UILabel resizes automatically now but my other problem is that the UITableView scroll is not smooth so ill have to fix that, and when i scroll in the UITableView the Cell data from the UILabel (labelMessage) seems to print it self in other cells, don't know why this is

单元格现在调整大小,UILabel现在自动调整大小,但我的另一个问题是UITableView滚动不顺利,所以不得不修复它,当我在UITableView中滚动时,来自UILabel(labelMessage)的Cell数据似乎打印出来在其他细胞中自我,不知道为什么会这样

BUT the Cells resize and the other issues ill ask another question on here.

但是,细胞调整大小,其他问题在这里问另一个问题。

Sorry forgot to add this bit of code that sits in the PostTableViewCell:

抱歉忘了添加位于PostTableViewCell中的这段代码:

        - (void)layoutSubviews
        {
            [super layoutSubviews];

            // Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
            // need to use to set the preferredMaxLayoutWidth below.
            [self.contentView setNeedsLayout];
            [self.contentView layoutIfNeeded];

            // Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
            // as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
            labelMessage.preferredMaxLayoutWidth = CGRectGetWidth(labelMessage.frame);
        }

#1


0  

So far i have got the cells to resize with Auto Layout but i have removed the UIView that sits inside the cell, so now i have three UILabels and an UIImageView which are the UIImageView (userImage), UILabel (labelUsername), UILabel (labelCreated) and UILabel (labelMessage). So the dimensions and coordinates are the same just that the UIView has been removed:

到目前为止,我已经使用自动布局调整了单元格,但是我已经删除了位于单元格内的UIView,所以现在我有三个UILabel和一个UIImageView,它们是UIImageView(userImage),UILabel(labelUsername),UILabel(labelCreated)和UILabel(labelMessage)。因此,尺寸和坐标与UIView被移除的相同:

First i set up NSLayoutContsraints in my Custom Cell, code bellow:

首先,我在自定义单元格中设置NSLayoutContsraints,代码如下:

Set numberOFLines = 0 and remove sizeToFit on the UILabel thats going to AutoLayout.

设置numberOFLines = 0并删除要转到AutoLayout的UILabel上的sizeToFit。

-(void)setupView:(PostInfo*)postInfo{


            CGRect screenRect = [[UIScreen mainScreen] bounds];
            viewPostMessage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, screenRect.size.width - 20, 100)];
            viewPostMessage.backgroundColor = [UIColor colorWithRed:193.0f/255 green:193.0f/255 blue:193.0f/255 alpha:1.0f];
            viewPostMessage.layer.borderColor = [UIColor blackColor].CGColor;
            viewPostMessage.layer.borderWidth = 0.5f;


            if(postInfo.userImage.length > 0){
            userImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
            UIImage *imageUser =  [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:@"http://www.hugt.co.uk/userimage/%d/userImage.jpg", postInfo.userId]]]];
            userImage.image = imageUser;
            [self.contentView addSubview:userImage];
            }else{
            UIView *viewImage = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)];
            viewImage.backgroundColor = [UIColor colorWithRed:132.0f/255 green:132.0f/255 blue:132.0f/255 alpha:1.0f];
            [self.contentView addSubview:viewImage];

            userImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
            UIImage *imageUser = [UIImage imageNamed:@"defaultuser.jpg"];
            userImage.image = imageUser;
            [viewImage addSubview:userImage];
            }

            labelUserName = [[UILabel alloc] initWithFrame:CGRectMake(50, 8, 200, 16)];
            labelUserName.textColor = [UIColor colorWithRed:56.0f/255 green:56.0f/255 blue:57.0f/255 alpha:1.0f];
            labelUserName.text = [NSString stringWithFormat:@"%@ %@ posted...", postInfo.firstName,postInfo.lastName];
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelUserName.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelUserName.userInteractionEnabled = YES;
            [self.contentView addSubview:labelUserName];

            labelCreated = [[UILabel alloc] initWithFrame:CGRectMake(50, 24, 200, 16)];
            labelCreated.textColor = [UIColor colorWithRed:86.0f/255 green:152.0f/255 blue:179.0f/255 alpha:1.0f];
            labelCreated.text = [NSDateFormatter localizedStringFromDate:postInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
            labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:@"AM" withString:@""];
            labelCreated.text = [labelCreated.text stringByReplacingOccurrencesOfString:@"PM" withString:@""];
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelCreated.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelCreated.userInteractionEnabled = YES;
            [self.contentView addSubview:labelCreated];

            labelMessage = [[UILabel alloc] initWithFrame:CGRectMake(50, 43, 210, 50)];
            labelMessage.textColor = [UIColor colorWithRed:141.0f/255 green:142.0f/255 blue:142.0f/255 alpha:1.0f];
            labelMessage.text = postInfo.message;
            labelMessage.numberOfLines = 0;
            //labelFirstName.textAlignment = NSTextAlignmentCenter;
            labelMessage.font = [UIFont fontWithName:@"Helvetica" size:12];
            labelMessage.userInteractionEnabled = YES;
            labelMessage.lineBreakMode = NSLineBreakByWordWrapping;
            //[labelMessage sizeToFit];
            [self.contentView addSubview:labelMessage];

            labelMessage.translatesAutoresizingMaskIntoConstraints = NO;

            [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[bodyLabel]-19-|" options:0 metrics:nil views:@{ @"bodyLabel": labelMessage }]];
            [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-43-[bodyLabel]-6-|" options:0 metrics:nil views:@{ @"bodyLabel": labelMessage }]];

            //[self.contentView addSubview:viewPostMessage];

        }

Then in my ViewController that contains the UITableVIew, i modified this bit of code:

然后在我的包含UITableVIew的ViewController中,我修改了这段代码:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
            static NSString *cellIdentifier = @"cell";
            if(tableViewThreads == tableView){

            return 122;

            }
            if(tableViewPosts == tableView){
            PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

            if (cell == nil)
            {
                cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
            }

            PostInfo *postInfo = (PostInfo*)[self.postsArray objectAtIndex:indexPath.row];
            [cell setupView:postInfo];

            [cell setNeedsLayout];
            [cell layoutIfNeeded];

            CGFloat h = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

            return h + 1;


            }
            return 0;
        }

The Cells do now resize and the UILabel resizes automatically now but my other problem is that the UITableView scroll is not smooth so ill have to fix that, and when i scroll in the UITableView the Cell data from the UILabel (labelMessage) seems to print it self in other cells, don't know why this is

单元格现在调整大小,UILabel现在自动调整大小,但我的另一个问题是UITableView滚动不顺利,所以不得不修复它,当我在UITableView中滚动时,来自UILabel(labelMessage)的Cell数据似乎打印出来在其他细胞中自我,不知道为什么会这样

BUT the Cells resize and the other issues ill ask another question on here.

但是,细胞调整大小,其他问题在这里问另一个问题。

Sorry forgot to add this bit of code that sits in the PostTableViewCell:

抱歉忘了添加位于PostTableViewCell中的这段代码:

        - (void)layoutSubviews
        {
            [super layoutSubviews];

            // Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
            // need to use to set the preferredMaxLayoutWidth below.
            [self.contentView setNeedsLayout];
            [self.contentView layoutIfNeeded];

            // Set the preferredMaxLayoutWidth of the mutli-line bodyLabel based on the evaluated width of the label's frame,
            // as this will allow the text to wrap correctly, and as a result allow the label to take on the correct height.
            labelMessage.preferredMaxLayoutWidth = CGRectGetWidth(labelMessage.frame);
        }