UINavigationBar的titleView添加UIImageView尺寸异常、不居中问题求解
现有代码的问题点
- 冗余创建了containerView但最终未使用,直接把imageView赋值给了titleView,且手动计算x轴偏移量完全没必要,titleView默认会被导航栏自动居中,手动修改frame会被UINavigationBar自身的布局逻辑覆盖,导致尺寸、位置异常
- 视图创建逻辑放在了
viewDidLayoutSubviews中,该方法会在布局变化时多次触发,会重复创建imageView并叠加,引发内存冗余和布局冲突 - 未设置imageView的内容尺寸约束,UINavigationBar的titleView会根据视图的
intrinsicContentSize自适应大小,仅手动设置frame不会生效
修复后的标准实现
将视图创建逻辑移到viewDidLoad中,给imageView添加固定宽高约束即可避免被导航栏拉伸,且能自动居中:
- (void)viewDidLoad { [super viewDidLoad]; UIImage *logoImage = [UIImage sdk_imageName:@"logo.png"]; CGFloat logoWidth = 10.0f; CGFloat logoHeight = 16.0f; UIImageView *logoImageView = [[UIImageView alloc] init]; logoImageView.contentMode = UIViewContentModeScaleAspectFit; logoImageView.image = logoImage; // 关键:添加固定宽高约束,避免导航栏自动拉伸视图 logoImageView.translatesAutoresizingMaskIntoConstraints = NO; [logoImageView.widthAnchor constraintEqualToConstant:logoWidth].active = YES; [logoImageView.heightAnchor constraintEqualToConstant:logoHeight].active = YES; self.navigationItem.titleView = logoImageView; }
其他可选实现方式
- 重绘图片为目标尺寸后直接使用:无需额外设置约束,直接将调整过尺寸的图片赋值给imageView即可
// UIImage分类的尺寸重写方法 - (UIImage *)scaleToSize:(CGSize)targetSize { UIGraphicsBeginImageContextWithOptions(targetSize, NO, [UIScreen mainScreen].scale); [self drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)]; UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage; } // 调用示例 UIImage *originalImage = [UIImage sdk_imageName:@"logo.png"]; UIImage *scaledImage = [originalImage scaleToSize:CGSizeMake(10, 16)]; self.navigationItem.titleView = [[UIImageView alloc] initWithImage:scaledImage]; - 若需要图片+文字等复杂标题布局,可创建自定义容器UIView,给容器添加固定宽高约束后,再在容器内部自由布局子控件即可。
内容的提问来源于stack exchange,提问作者stefanosn
相关产品推荐
相关产品推荐

