UITableViewCell 使用自定义单元格滚动不平滑

Posted

技术标签:

【中文标题】UITableViewCell 使用自定义单元格滚动不平滑【英文标题】:UITableViewCell scroll not smooth with custom cell 【发布时间】:2016-11-07 14:25:21 【问题描述】:

这是cellForRowAtIndexPath

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

    MessageDetailCell *cell;
    @try 
        if(indexPath != nil && indexPath.row < arrMessages.count)
        
            cell = [tableView dequeueReusableCellWithIdentifier:@"MessageDetailCell"];
            if (cell == nil) 
                NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"MessageDetailCell" owner:self options:nil];
                cell = [topLevelObjects objectAtIndex:0];
                cell.selectionStyle = UITableViewCellSelectionStyleNone;
                cell.accessoryType = UITableViewCellAccessoryNone;
                if ([cell respondsToSelector:@selector(layoutMargins)]) 
                    cell.layoutMargins = UIEdgeInsetsZero;
                    cell.preservesSuperviewLayoutMargins = false;
                
            
            else
            
                NSArray *arr = [cell.contentView subviews];
                for(int i=0; i<[arr count]; i++)
                
                    UIView *view = [arr objectAtIndex:i];
                    [view removeFromSuperview];
                
            

            cell.tag = indexPath.row;
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.accessoryType = UITableViewCellAccessoryNone;

            MessageThread *thread = [arrMessages objectAtIndex:indexPath.row];
            float xAxis = 10.0;
            float yAxis = 10.0;
            float imageDimention = 40;
            float fontSize = 20;

            NSLog(@"");
            if(indexPath.row == 0)
            
                xAxis = 10;
                imageDimention = 40;
                fontSize = 20;
                cell.imgUserWidthConstraint.constant = 40;
                cell.imgUserHeightConstraint.constant = 40;
                cell.lblContentLeftConstraint.constant = 64;
                cell.btnReplyLeftConstraint.constant = 64;
            
            else
            
                xAxis = 32 * thread.ReplyLevel;
                imageDimention = 32;
                fontSize = 17;
                cell.imgUserWidthConstraint.constant = 32;
                cell.imgUserHeightConstraint.constant = 32;
                cell.lblContentLeftConstraint.constant = 110;
                cell.btnReplyLeftConstraint.constant = 110;
            

                if(![thread.sender.Image isEqual:@""] && ![thread.sender.Image.lowercaseString containsString:@"default"])
                        [self createImage:CGRectMake(xAxis, yAxis, imageDimention, imageDimention) cell:cell messageThread:thread];
                else
                
                    UILabel *lblLetter = [[UILabel alloc]initWithFrame:CGRectMake(xAxis, yAxis, imageDimention, imageDimention)];
                    lblLetter.layer.cornerRadius = lblLetter.frame.size.width / 2;
                    lblLetter.layer.borderColor = [[UIColor blackColor] CGColor];
                    lblLetter.layer.borderWidth = 0.8;
                    lblLetter.layer.masksToBounds = YES;
                    lblLetter.backgroundColor = [UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:239.0/255.0 alpha:1.0];
                    lblLetter.text = [thread.sender.FirstName substringToIndex:1];
                    lblLetter.font = [UIFont boldSystemFontOfSize:fontSize];
                    lblLetter.textAlignment = NSTextAlignmentCenter;
                    lblLetter.textColor = [UIColor blackColor];
                    [cell.contentView addSubview:lblLetter];
                

                cell.imgUserLeftConstraint.constant = xAxis;
                xAxis = 80;

            NSString *recipients = @"";

            for(Recipient *rp in thread.Recipients)
            
                recipients = [recipients stringByAppendingString:[NSString stringWithFormat:@"%@, ", rp.Name]];
            

            recipients = [recipients substringToIndex:recipients.length - 2];


            NSAttributedString * attrUserText;
            attrUserText = [[NSAttributedString alloc] initWithData:[[NSString stringWithFormat:@"%@ &rarr; %@", thread.sender.FullName, recipients] dataUsingEncoding:NSUnicodeStringEncoding] options:@ NSDocumentTypeDocumentAttribute: NShtmlTextDocumentType  documentAttributes:nil error:nil];

            NSAttributedString *attrArrow = [[NSAttributedString alloc] initWithData:[[NSString stringWithFormat:@" &rarr; %@", recipients] dataUsingEncoding:NSUnicodeStringEncoding] options:@ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType  documentAttributes:nil error:nil];

             NSMutableAttributedString *string =  [[NSMutableAttributedString alloc]initWithAttributedString:attrUserText];

            int firstHalf = (int)thread.sender.FullName.length;
            int secondHalf = (int)attrArrow.length;

            [string addAttribute:NSForegroundColorAttributeName value:[UIColor lightGrayColor] range:NSMakeRange(firstHalf,secondHalf + 1)];
            [string addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0,firstHalf)];

            cell.lblUsers.attributedText = string;

            cell.lblUsers.textAlignment = NSTextAlignmentLeft;
            cell.lblUsers.font = [UIFont boldSystemFontOfSize:15];
            cell.lblUsers.numberOfLines = 0;

            cell.lblDate.text = [self returnDate:thread.CreatedOn];
            cell.lblDateTopConstraint.constant = 10;
            cell.lblDate.textAlignment = NSTextAlignmentLeft;
            cell.lblDate.font = [UIFont systemFontOfSize:12];

            cell.lblContent.tag = (int)indexPath.row;
            cell.lblContent.backgroundColor = [UIColor clearColor];
            cell.lblContent.textColor = [UIColor blackColor];
            cell.lblContent.textAlignment = NSTextAlignmentLeft;
            cell.lblContent.font = [UIFont systemFontOfSize:14];
            cell.lblContent.text = thread.MessageContent;
            cell.lblContent.dataDetectorTypes = UIDataDetectorTypeLink;
            cell.lblContent.dataDetectorTypes = UIDataDetectorTypeAll;
            cell.lblContent.scrollEnabled = NO;
            cell.lblContent.editable = NO;
            cell.lblContent.selectable = YES;
            cell.lblContent.contentInset = UIEdgeInsetsMake(0, -4, 0, 0);
            [cell.lblContent layoutIfNeeded];
//
            yAxis = yAxis + 30;

            float yAxisDocAttachment = 0;
            cell.viewAttachmentHeightConstraint.constant = 0;
            BOOL isDoc = NO;
            BOOL isImage = NO;


            if(thread.attachments.count > 0)
            
                for(MessageAttachment *msgDoc in thread.attachments)
                
                    if(![msgDoc.Type isEqual:@"Image"])
                    
                        isDoc = YES;
                        cell.viewAttachmentCollection.hidden = NO;
                        cell.viewAttachmentTopConstraint.constant = 10;
                        if((int)indexPath.row != 0)
                            cell.viewAttachmentLeftConstraint.constant = xAxis - 16;
                        else
                            cell.viewAttachmentLeftConstraint.constant = xAxis;
                        UIView *viewAttachment = [[UIView alloc]initWithFrame:CGRectMake(0, yAxisDocAttachment, self.view.frame.size.width - cell.lblContent.frame.origin.x - 50, 80)];
                        viewAttachment.backgroundColor = [UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];
                        viewAttachment.tag = indexPath.row;
                        viewAttachment.accessibilityIdentifier = msgDoc.Url;
                        viewAttachment.accessibilityLabel = msgDoc.Name;
                        [cell.viewAttachmentCollection addSubview:viewAttachment];

                        UIImageView *imgAttachment = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 52, 60)];
                        imgAttachment.image = [UIImage imageNamed:@"document.png"];
                        [viewAttachment addSubview:imgAttachment];

                        UILabel *lblFileName = [[UILabel alloc]initWithFrame:CGRectMake(65, 5, viewAttachment.frame.size.width - 65, 22)];
                        lblFileName.backgroundColor = [UIColor clearColor];
                        lblFileName.text = msgDoc.Name;
                        lblFileName.text = [lblFileName.text stringByReplacingOccurrencesOfString:@"%20" withString:@" "];
                        lblFileName.textAlignment = NSTextAlignmentLeft;
                        lblFileName.font = [UIFont systemFontOfSize:10];
                        lblFileName.numberOfLines = 0;
                        [viewAttachment addSubview:lblFileName];
                        [lblFileName sizeToFit];

                        UILabel *lblFileType = [[UILabel alloc]initWithFrame:CGRectMake(65, 30, viewAttachment.frame.size.width - 65, 20)];
                        lblFileType.backgroundColor = [UIColor clearColor];
                        lblFileType.text = msgDoc.Name;
                        lblFileType.textAlignment = NSTextAlignmentLeft;
                        lblFileType.font = [UIFont systemFontOfSize:10];
                        [viewAttachment addSubview:lblFileName];

                        UILabel *lblDownload = [[UILabel alloc]initWithFrame:CGRectMake(65, 53, viewAttachment.frame.size.width - 65, 20)];
                        lblDownload.backgroundColor = [UIColor clearColor];
                        lblDownload.text = NSLocalizedString(@"click_to_download", nil);
                        lblDownload.textAlignment = NSTextAlignmentLeft;
                        lblDownload.font = [UIFont systemFontOfSize:10];
                        [viewAttachment addSubview:lblDownload];

                        UITapGestureRecognizer *gestureAttachment = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleAttachmentGesture:)];
                        [viewAttachment addGestureRecognizer:gestureAttachment];

                        yAxis = yAxis + 90;
                        yAxisDocAttachment = yAxisDocAttachment + 90;
                        cell.viewAttachmentHeightConstraint.constant = cell.viewAttachmentHeightConstraint.constant + 90;
                    
                

                cell.viewImageHeightConstraint.constant = 0;
                if(indexPath.row != 0)
                    cell.viewImageLeftConstraint.constant = xAxis - 16;
                else
                    cell.viewImageLeftConstraint.constant = xAxis;
                for(MessageAttachment *msgDoc in thread.attachments)
                
                    if([msgDoc.Type isEqual:@"Image"])
                    
                        isImage = YES;
                        cell.viewImageCollection.hidden = NO;
                        cell.viewImageTopConstraint.constant = 10;
                        cell.btnReplyTopConstraint.constant = 10;
                        [self createAttachmentImage:CGRectMake(xAxis, cell.viewImageHeightConstraint.constant + 10, self.view.frame.size.width - xAxis - 5, 480) cell:cell message:msgDoc indexPath:indexPath];
                        cell.viewImageHeightConstraint.constant = cell.viewImageHeightConstraint.constant + 5;
                    
                
            

            if(!isDoc)
            
                cell.viewAttachmentCollection.hidden = YES;
                cell.viewAttachmentHeightConstraint.constant = 0;
                cell.viewAttachmentTopConstraint.constant = 0;
            
            if(!isImage)
            
                cell.viewImageCollection.hidden = YES;
                cell.viewImageHeightConstraint.constant = 0;
                cell.viewImageTopConstraint.constant = 0;
            

            [cell.btnReplyCell setTitle:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"reply", nil),thread.sender.FirstName] forState:UIControlStateNormal];
            [cell.btnReplyCell setTitle:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"reply", nil),thread.sender.FirstName] forState:UIControlStateDisabled];
            [cell.btnReplyCell setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [cell.btnReplyCell setTitleColor:[UIColor colorWithRed:199.0/255.0 green:192.0/255.0 blue:193.0/255.0 alpha:1.0] forState:UIControlStateDisabled];

            if(thread.sender.SenderId != [[NSString stringWithFormat:@"%@", [[NSUserDefaults standardUserDefaults]objectForKey:@"UserId"]] intValue])
            
                cell.btnReplyTopConstraint.constant = 10;
                cell.btnReplyHeightConstraint.constant = 30;
                cell.btnReplyBottomConstraint.constant = 12;
                cell.btnReplyCell.titleLabel.textAlignment = NSTextAlignmentCenter;
                cell.btnReplyCell.layer.cornerRadius = 7;
                cell.btnReplyCell.tag = (int)indexPath.row;
                cell.btnReplyCell.backgroundColor = [UIColor whiteColor];
                cell.btnReplyCell.layer.borderColor = [[UIColor blackColor] CGColor];
                cell.btnReplyCell.layer.borderWidth = 0.7;
                cell.btnReplyCell.accessibilityIdentifier = [NSString stringWithFormat:@"%i", (int)arrBtnReply.count];
                cell.btnReplyCell.titleLabel.font = [UIFont systemFontOfSize:12];
                [cell.btnReplyCell addTarget:self action:@selector(replyTapped:) forControlEvents:UIControlEventTouchUpInside];
                yAxis = yAxis + 20;
                cell.btnReplyCell.accessibilityLabel = [NSString stringWithFormat:@"%f", yAxis];
                cell.btnReplyCell.enabled = YES;
                cell.btnReplyTopConstraint.constant = 10;
            
            else
            
                cell.btnReplyTopConstraint.constant = 10;
                cell.btnReplyBottomConstraint.constant = 0;
                cell.btnReplyCell.hidden = YES;
                cell.btnReplyHeightConstraint.constant = 0;
                cell.btnReplyCell.layer.cornerRadius = 7;
                cell.btnReplyCell.backgroundColor = [UIColor colorWithRed:224.0/255.0 green:224.0/255.0 blue:224.0/255.0 alpha:1.0];
                cell.btnReplyCell.enabled = NO;
            

            [cell updateConstraintsIfNeeded];
            [cell setNeedsLayout];
            [cell layoutIfNeeded];
            return cell;
        
    
    @catch (NSException *exception) 
        return cell;
    

我知道那巨大的代码,但是什么会打断平滑滚动?

【问题讨论】:

你能附上这个单元格的截图吗? 【参考方案1】:

我描述了一些假设:

您配置了许多约束。这不利于平滑滚动。如果您的单元格很复杂,因此有很多限制 -> 您可以看到抽动的滚动条。 我还可以看到您动态添加/删除子视图。你为什么这么做?为什么不在init方法中配置label呢? 有时shadowcornerRadius 会影响平滑滚动。

我认为你的主要问题是约束和动态添加/删除视图。

【讨论】:

以上是关于UITableViewCell 使用自定义单元格滚动不平滑的主要内容,如果未能解决你的问题,请参考以下文章

使用带有原型单元的自定义 UITableViewCell

UITableViewCell 使用自定义单元格滚动不平滑

自定义 UITableViewCell 前导对齐到右细节单元格

在 iOS 中使用自定义单元格时无法查看 UITableViewCell

错误:无法使用自定义单元格类设置 UITableViewCell 标签和图像!只能加载单元格样式的数据:字幕不是自定义的

在 UITableViewCell 中获取自定义单元格的高度