iOS 11的navigationItem.titleView宽度未设置

使用navigationItem.titleView在iOS11上查看行为,其中titleView的宽度不是屏幕的整个宽度。

我有一个自定义的视图,我设置为titleView。 在iOS11之前,视图会填充导航栏区域。 但是iOS 11并没有调整屏幕宽度。

我试图在设置titleView之前设置视图的框架,但没有运气。 我试图强制titleviews superview布局约束,但没有运气。

截图附件:

iOS10:

在这里输入图像说明

iOS11:

在这里输入图像说明

任何人都经历过这个?

我想到了。 我不得不重写视图的intrinsicContentSize getter和文本字段。

我将宽度设置为CGFloat.greatestFiniteMagnitude,使其始终与屏幕一样宽。

更新:

由于我在这个问题上花了几个小时,所以希望其他人能够把所有事情紧紧凑在一起

我创build了一个称为CustomTitleViewTitleView自定义子类, TitleView是代码:

 import UIKit class CustomTitleView: UIView { override var intrinsicContentSize: CGSize { return UILayoutFittingExpandedSize } } 

而我从一开始就错过的最重要的部分是:

在这里输入图像说明

使用@ falkon的答案这里是代码:

将此代码添加到用作titleView的视图

 override var intrinsicContentSize: CGSize { return UILayoutFittingExpandedSize } 

intrinsicContentSize设置为UILayoutFittingExpandedSize也可以

通过创buildUIView的子类来修复它,并将其分配给导航控制器的标题视图

Objectve-C:

 #import "FLWCustomTitleView.h" @implementation FLWCustomTitleView - (CGSize )intrinsicContentSize { return UILayoutFittingExpandedSize; } @end 

在这里输入图像说明 在这里输入图像说明

最重要的是,你需要覆盖customTitleView作为你的titleView:

self.navigationItem.titleView = [self titleView];

 #pragma mark - getter - (UIView *)titleView { UIView *navTitleView = [HFCalenderTitleView new]; navTitleView.frame = CGRectMake(0.0, 0.0, HorizontalFrom750(200.0), 44.0); [navTitleView addSubview:self.titleLabel]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(navTitleView); }]; CGFloat btnWidth = 30.0; [navTitleView addSubview:self.previousButton]; self.previousButton.imageEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 15.0); [self.previousButton mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(navTitleView); make.top.bottom.equalTo(navTitleView); make.width.equalTo(@(btnWidth)); }]; [navTitleView addSubview:self.nextBtn]; self.nextBtn.imageEdgeInsets = UIEdgeInsetsMake(0.0, 15.0, 0.0, 0.0); [self.nextBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(navTitleView); make.top.bottom.equalTo(navTitleView); make.width.equalTo(@(btnWidth)); }]; return navTitleView; } #pragma mark - customTitleView #import "HFCalenderTitleView.h" @implementation HFCalenderTitleView - (CGSize)intrinsicContentSize{ return CGSizeMake(HorizontalFrom750(200.0), 40); // the target size } 

在这里输入图像说明

在这里输入图像说明

如果您不想重写intrinsicContentSize也可以使用约束。 这是一个SnapKit的演示

 self.navigationItem.titleView = titleView if #available(iOS 11, *) { titleView.snp.makeConstraints({ (make) in make.width.equalTo(250) // fixed width make.height.equalTo(30) // less than 44(height of naviagtion bar) }) }else { titleView.frame = ... } 

但是,如果任何一侧(左侧或右侧)导航栏上有多个导航栏,则应使用intrinsicContentSize;

我有同样的问题,但设置UIImage作为navigationItem titleView

我所做的是我通过使用下面的图像缩放到所需的大小:

 -(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

并称之为如下:

 -(void)setHeaderImage{ UIImage * image = [self imageWithImage:[UIImage imageNamed:@"headerImage"] scaledToSize:CGSizeMake(150, 27)]; UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.frame = CGRectMake(0, 0, 150, 27); imageView.contentMode = UIViewContentModeScaleAspectFit; self.navigationItem.titleView = imageView; } 

当你在CustomTitleView里面有一个UIView作为子视图的时候,intrinsicContentSize解决scheme对我来说只适用于iOS 11中的XCODE 9。 所以我喜欢下面,对我来说工作得很好,可以帮助别人。

 @interface CustomTitleView : UIView @property (weak, nonatomic) IBOutlet UIView *doubleTitleView; @end @implementation CustomTitleView - (void)awakeFromNib { [super awakeFromNib]; int width = _doubleTitleView.frame.size.width; int height = _doubleTitleView.frame.size.height; if (width != 0 && height != 0) { NSLayoutConstraint *widthConstraint = [_doubleTitleView.widthAnchor constraintEqualToConstant:width]; NSLayoutConstraint *heightConstraint = [_doubleTitleView.heightAnchor constraintEqualToConstant:height]; [_doubleTitleView addConstraint:heightConstraint]; [_doubleTitleView addConstraint:widthConstraint]; [heightConstraint setActive:TRUE]; [widthConstraint setActive:TRUE]; } } 

return UILayoutFittingExpandedSize没有帮助我,因为视图被垂直添加了几次来填充布局。

解决的办法是将自定义视图中的intrinsicContentSize设置为最大宽度:

  - (CGSize)intrinsicContentSize { //fills empty space. View will be resized to be smaller, but if it is too small - then it stays too small CGRect frame = self.frame; frame.size.width = MAX(SCREEN_WIDTH, SCREEN_HEIGHT); return frame.size; } 

我不得不将UIImageView作为navigationItem.titleView。 纵横比确实适合,但是intrinsicContentSize使其变大。 缩放图像导致图像质量差。 设置布局锚为我工作:

 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 30)]; [imageView setImage:image]; [imageView.widthAnchor constraintEqualToConstant:80].active = YES; [imageView.heightAnchor constraintEqualToConstant:30].active = YES; [imageView setContentMode:UIViewContentModeScaleAspectFit]; self.navigationItem.titleView = imageView;