乐趣区

关于ios:iOS计算Label的最合适的Size

iOS 中常常有须要给 Label 一个最合适的宽度和高度,京东和淘宝的搜寻历史就是个典型利用:

对于计算方法,以前始终应用的是 NSString 的一个办法:

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attributes context:(nullable NSStringDrawingContext *)context API_AVAILABLE(macos(10.11), ios(7.0));

应用的例子如下,这里是想获取适合的宽度,就要给宽度传入一个很大的值,而后高度给一个固定的值:

- (CGFloat)textWidth:(NSString *)text {CGFloat width =} context:nil].size.width + 20;
    
    return width;
}

然而这个办法其实很不精确,所以大多还会在返回的根底上,加一个值,例如下面这个代码就加 20,以防止给的宽度过小,导致无奈显示齐全。
可即便这样做了,返回的这个宽度,我发现依然有可能偏小,并会引起一些 UI 问题,例如我在做这个历史搜寻界面的时候,就发现有些 label,最右面会有一条线,如下所示:

我一开始认为是我不小心加了一条线在 Label 上,后果用 xcode 查看了视图层级,发现没有其余图层了,我狐疑可能给的这个宽度不对,导致呈现的这个问题,我采纳了另外的办法,这个是 UIView 的一个办法,不过宽度不对,导致这条线呈现的更深层次的起因,应该是 UILabel 的实现的问题。

- (CGSize)sizeThatFits:(CGSize)size;     // return 'best' size to fit given size. does not actually resize view. Default is return existing view size

官网的正文曾经通知咱们这个,这个能够给出最佳的 size,应用的时候必须是曾经实例化进去的 View,比方 Label 的话,要先初始化,而后赋值 text 和 font,例子如下:

    UILabel *contentLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    contentLabel.font = [UIFont systemFontOfSize:14];
    contentLabel.text = historyArray[i];
    CGFloat nowWidth = [self widthForLabel:contentLabel andheight:kSearchHistorySubViewHeight]
    ......
- (CGFloat)widthForLabel:(UILabel *)label andheight:(CGFloat)height {CGSize sizeToFit = [label sizeThatFits:CGSizeMake(MAXFLOAT, height)];
    CGFloat width = sizeToFit.width + 10;

    return width;
}

这个计算出的宽度的确准确,但都贴着字符的边了,所以咱们要加点宽度,不然很不美观。当前 label 再须要计算准确的宽度或高度,最好用这个办法了。

退出移动版