1、Xcode16环境运行iOS18.1系统真机时YYLabel富文本中图片设置baselineOffset导致布局错乱问题
场景:
使用YYLabel实现文字与图片混合,其中图片需要做到向上偏移5像素
错误的实现方式:
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@", model.shop_recommend.tab_title]];
attr.yy_font = BOLDFONT(13);
attr.yy_color = COLOR(0x666666);
if ([UserTransaction.sharedInstance livingShopRedDotShow]) {
NSMutableAttributedString *redDotString = [NSMutableAttributedString yy_attachmentStringWithContent:[UIImage imageWithColor:COLOR(0xff3e03) size:CGSizeMake(5, 5) cornerRadius:2.5] contentMode:UIViewContentModeRight attachmentSize:CGSizeMake(7, 5) alignToFont:BOLDFONT(13) alignment:YYTextVerticalAlignmentCenter];
redDotString.yy_baselineOffset = @5;
[attr appendAttributedString:redDotString];
}
UIImage *iconImage = nil;
if (model.shop_recommend.isUnfold) {
iconImage = [UIImage imageNamed:@"fs_ecommerce_shouqi"];
}else {
iconImage = [UIImage imageNamed:@"fs_ecommerce_xiala"];
}
NSMutableAttributedString *imageString = [NSMutableAttributedString yy_attachmentStringWithContent:iconImage contentMode:UIViewContentModeRight attachmentSize:CGSizeMake(15, 6) alignToFont:BOLDFONT(13) alignment:YYTextVerticalAlignmentCenter];
imageString.yy_baselineOffset = @1;
[attr appendAttributedString:imageString];
YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
container.maximumNumberOfRows = 1;
YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:attr];
CGFloat ecommerceWidth = layout.textBoundingSize.width;
[self.programLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-(15 + ecommerceWidth + 10));
}];
[self.ecommerceLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(ecommerceWidth);
}];
self.ecommerceLabel.attributedText = attr;
如上代码中为了实现图片向上偏移,使用了配置baselineOffset
的方式redDotString.yy_baselineOffset = @5;
,但测试过程中发现在Xcode16且iOS系统为18.1的时候YYLabel文字发生了偏移,布局错乱了
Xcode15.4上可以正常显示,在Xcode16上出现该问题。
解决方案:
YYKit框架中的yy_attachmentStringWithContent:contentMode:attachmentSize:alignToFont:alignment
函数的content可以传入UIImageView,使用UIImageView替换UIImage并设置其contentMode和尺寸,运行后正常布局了。
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@", model.shop_recommend.tab_title]];
attr.yy_font = BOLDFONT(13);
attr.yy_color = COLOR(0x666666);
if ([UserTransaction.sharedInstance livingShopRedDotShow]) {
UIImageView *redDotImageView = [[UIImageView alloc] init];
redDotImageView.image = [UIImage imageWithColor:COLOR(0xff3e03) size:CGSizeMake(5, 5) cornerRadius:2.5];
redDotImageView.contentMode = UIViewContentModeTopRight;
// redDotImageView.backgroundColor = UIColor.orangeColor;
redDotImageView.frame = CGRectMake(0, 0, 7, 16);
NSMutableAttributedString *redDotString = [NSMutableAttributedString yy_attachmentStringWithContent:redDotImageView contentMode:UIViewContentModeRight attachmentSize:CGSizeMake(7, 16) alignToFont:BOLDFONT(13) alignment:YYTextVerticalAlignmentCenter];
[attr appendAttributedString:redDotString];
}
UIImage *iconImage = nil;
if (model.shop_recommend.isUnfold) {
iconImage = [UIImage imageNamed:@"fs_ecommerce_shouqi"];
}else {
iconImage = [UIImage imageNamed:@"fs_ecommerce_xiala"];
}
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = iconImage;
imageView.contentMode = UIViewContentModeRight;
// imageView.backgroundColor = UIColor.greenColor;
imageView.frame = CGRectMake(0, 0, 15, 16);
NSMutableAttributedString *imageString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeRight attachmentSize:CGSizeMake(15, 16) alignToFont:BOLDFONT(13) alignment:YYTextVerticalAlignmentCenter];
[attr appendAttributedString:imageString];
YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
container.maximumNumberOfRows = 1;
YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:attr];
CGFloat ecommerceWidth = layout.textBoundingSize.width;
[self.programLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-(15 + ecommerceWidth + 10));
}];
[self.ecommerceLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(ecommerceWidth);
}];
self.ecommerceLabel.attributedText = attr;