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

IOS,如何在包含不同子视图的UITableViewCell中设置自动布局,ios,objective-c,Ios,Objective C,我有一个布局问题,我有一个包含UIImageView和其他三个UILabel的UIView。需要动态设置布局的部分是添加到单元格的主UIView和包含任意长度文本的UILabel(例如本例中的文本) 我创建了一个自定义UITableViewCell,并将子视图添加到自定义UITableViewCell,如下所示: -(void)setupView:(PostInfo*)postInfo{ CGRect screenRect = [[UIScreen m

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

我创建了一个自定义UITableViewCell,并将子视图添加到自定义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];

        }
创建此自定义UITableViewCell时,我传入一个对象,该对象设置UILabels上的文本,如下所示:

-(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;
        }
我搜索了网页,也在这里找到了如何在单元格中自动布局子视图,但似乎无法理解接下来需要做什么。我了解到您需要一个原型单元格,所以我创建了一个自定义UITableViewCell,这就是我所做的


任何帮助都将不胜感激。

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

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

将numberOFLines设置为0,并删除要自动布局的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];

        }
然后,在包含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;
        }
单元格现在会自动调整大小,UILabel现在会自动调整大小,但我的另一个问题是UITableView滚动不平滑,因此我必须解决这个问题,当我在UITableView中滚动时,UILabel(labelMessage)中的单元格数据似乎会在其他单元格中自行打印,我不知道这是为什么

但是单元格的大小和其他问题我会在这里问另一个问题

抱歉,忘记添加位于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);
        }

我看到的一个大问题是使用
NSData-dataWithContentsOfURL:
。除非您知道这些映像是缓存的,否则这是对网络的阻塞(同步)调用,不应该在主线程上执行(我假设您的-setupView:正在运行)。因此,我必须使用dispatch queueYeah,这将是加载映像的一种方法。但是,您需要切换回主队列,以便在UIImageView上实际设置UIImage。你也可以使用。UIImageView上有一个sweet类别,用于异步加载/设置图像。谢谢,伙计,我会试试的