iOS小技能:UILabel展示三行,如果超过三行显示下拉icon或者更多...

744 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

引言

需求: 设备描述最多展示三行,如果超过三行显示下拉icon。

I 前置知识

1.1 约束优先级

例子: 设置购买按钮的底部约束优先级最高,来实现动态控制cell的高度。

        [tmpView mas_makeConstraints:^(MASConstraintMaker *make) {
            
            
            
            
            make.right.equalTo(weakSelf).offset(kAdjustRatio(-kSideMargin));
            
            
            make.top.greaterThanOrEqualTo(weakSelf.skuLab.mas_bottom).offset(kAdjustRatio(6)).priorityLow();
            

                        make.bottom.lessThanOrEqualTo(weakSelf).offset(kAdjustRatio(-20)).priorityHigh();
            
            
    
            
            
            
            
        }];

1.2 tableView的高性能更新方式

通过tableView的reloadData⽅法我们可以⽅便的对tableVie的cell根据数据源进⾏刷新。但是这种刷新⽅法在某些时候也不是那么合适。⽐如只 需要更新⼏⾏的时候可能显得多余。同时在tableView较为复杂的时候还会产⽣性能的问题。

在这种时候我们可以使⽤tableView的beginUpdates⽅法和endUpdates⽅法来对tableView的⼏⾏数据进⾏增删改和对cell的位置移动。

系统会⾃动给我们的操作加上动画

1.3 设置文字过长时的显示格式

label.lineBreakMode = NSLineBreakByCharWrapping;//以字符为显示单位显示,后面部分省略不显示。
label.lineBreakMode = NSLineBreakByClipping;//剪切与文本宽度相同的内容长度,后半部分被删除。
label.lineBreakMode = NSLineBreakByTruncatingHead;//前面部分文字以……方式省略,显示尾部文字内容。
label.lineBreakMode = NSLineBreakByTruncatingMiddle;//中间的内容以……方式省略,显示头尾的文字内容。
label.lineBreakMode = NSLineBreakByTruncatingTail;//结尾部分的内容以……方式省略,显示头的文字内容。
label.lineBreakMode = NSLineBreakByWordWrapping;//以单词为显示单位显=示,后面部分省略不显示。
typedef NS_ENUM(NSInteger, NSLineBreakMode) {
    NSLineBreakByWordWrapping = 0,         // Wrap at word boundaries, default
    NSLineBreakByCharWrapping,        // Wrap at character boundaries
    NSLineBreakByClipping,        // Simply clip
    NSLineBreakByTruncatingHead,    // Truncate at head of line: "...wxyz"
    NSLineBreakByTruncatingTail,    // Truncate at tail of line: "abcd..."
    NSLineBreakByTruncatingMiddle    // Truncate middle of line:  "ab...yz"
} API_AVAILABLE(macos(10.0), ios(6.0), watchos(2.0), tvos(9.0));


UILabel 限定长度时,内容过多,最后不显示"..."

    self.skuLab.lineBreakMode=NSLineBreakByCharWrapping;
    

1.4 计算UILabel行数

/**
 1. UIFont 有一个 lineHeight. 先用UILabel的 sizeToFit 计算出最佳大小。
 2. 用高度/lineHeight就是行数
 
 - (void)sizeToFit;                       // calls sizeThatFits: with current view bounds and changes bounds size.


 */
+ (NSInteger)getlineCountHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font

{
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 0)];
    label.text = title;
    label.font = font;
    label.numberOfLines = 0;
    [label sizeToFit];
    CGFloat height = label.frame.size.height;
    NSLog(@"%f",height);
    
    NSNumber *count = @((height) / label.font.lineHeight);
    
    NSLog(@"共 %td 行", [count integerValue]);
    return [count integerValue];
    
}



II UILabel展示三行,如果超过三行显示下拉icon。

更新视图的数据模型时,判断文本行数,进行控制下拉icon的显示与隐藏

    NSInteger  count =  [ControlManager getlineCountHeightByWidth:(kWidth-(kSideMargin*2)-kcellSideMargin-self.iconImgV.width )  title:describe font:self.skuLab.font];
    
    self.skuLab.numberOfLines = 3;
//UILabel 限定长度时,内容过多,最后不显示"..."
    self.skuLab.lineBreakMode=NSLineBreakByCharWrapping;
    

//下拉按钮和上拉按钮 可以通过选择180度进行转换
    if(count<=3){
        
// 显示上下拉按钮icon_down_up
//        self.icon_down_up.hidden =
        
        [self.icon_down_up mas_updateConstraints:^(MASConstraintMaker *make) {
           
            make.size.mas_equalTo(CGSizeZero);
            
        }];
    
    }else{
        

        //显示上下拉按钮
        
        [self.icon_down_up mas_updateConstraints:^(MASConstraintMaker *make) {
           
            make.size.mas_equalTo(CGSizeMake(kAdjustRatio(8), kAdjustRatio(8)));

        }];
        

    }

III 显示全部内容

3.1 处理下拉事件

                tmpView.numberOfLines = 0;

3.2 处理上拉事件

                tmpView.numberOfLines = 3;

IV 更新约束

4.1 有动画效果

    ERPEquipmentProcurementCell *cell = [ERPEquipmentProcurementCell tableViewCellWithTableView:tableView block:^(id  _Nonnull sender) {
        
        
        [weakSelf.tableView beginUpdates];
        
        [weakSelf.tableView endUpdates];
        


        
    } models:model];

监听点击事件

        tmpView.userInteractionEnabled = YES;
        UITapGestureRecognizer *cutTap = [[UITapGestureRecognizer alloc] init];
        [[cutTap rac_gestureSignal] subscribeNext:^(id x) {
                        
            NSLog(@" cutTap 点击了 ");
            
//
            if ( tmpView.numberOfLines==3) {
                
                
                tmpView.numberOfLines = 0;
                
                
            }else{
                
                tmpView.numberOfLines = 3;
                
            }
            
            if (weakSelf.block) {
                weakSelf.block(x);
                
            }
            
            
            
        }];
        
        [tmpView addGestureRecognizer:cutTap];
        
        
        
    }

4.2 无动画效果

使用 [weakSelf.tableView reloadData];进行更新约束,但是需要把数据存入数据模型。

        tmpView.userInteractionEnabled = YES;
        UITapGestureRecognizer *cutTap = [[UITapGestureRecognizer alloc] init];
        [[cutTap rac_gestureSignal] subscribeNext:^(id x) {
                        
            NSLog(@" cutTap 点击了 ");
            
//
            if ( tmpView.numberOfLines==3) {
                
                
                self.models.numberOfLines = 0;
                
                
                
            }else{
                
                self.models.numberOfLines =3;
                

                
            }
            
            if (weakSelf.block) {
                weakSelf.block(x);
                
            }
            
            
            
        }];
        
        [tmpView addGestureRecognizer:cutTap];
        
        
        
    }