iOS 11 navigationItem.titleView 宽度未设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44932084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:18:20  来源:igfitidea点击:

iOS 11 navigationItem.titleView Width Not Set

iosuinavigationcontrolleruinavigationbarios11navigationitem

提问by gngrwzrd

Seeing a behavior on iOS11 with a navigationItem.titleView where the width of the titleView is not the full width of the screen.

在 iOS11 上看到一个带有 navigationItem.titleView 的行为,其中 titleView 的宽度不是屏幕的全宽。

I have a custom view that I set as the titleView. Previous to iOS11 the view would fill the navigation bar area. But iOS 11 it is not resizing to fill the width of the screen.

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

I've tried setting the frame of the view before setting titleView but no luck. I've tried to force the titleViews superview to layout constraints as well but no luck.

我已经尝试在设置 titleView 之前设置视图的框架,但没有运气。我也试图强制 titleViews 超级视图进行布局约束,但没有运气。

Screenshots attached:

附上截图:

iOS10:

iOS10:

enter image description here

在此处输入图片说明

iOS11:

iOS11:

enter image description here

在此处输入图片说明

Anyone else experience this?

还有其他人经历过吗?

回答by gngrwzrd

I figured it out. I had to override the intrinsicContentSize getter for the view, and the text field.

我想到了。我必须覆盖视图的内在内容大小 getter 和文本字段。

I set the width to CGFloat.greatestFiniteMagnitude so it'll always be as wide as the screen.

我将宽度设置为 CGFloat.greatestFiniteMagnitude,所以它总是和屏幕一样宽。

Update:

更新:

Since I've spent couple of hours on this issue, hope that some else will catch up faster by having all things tight up together

由于我已经在这个问题上花费了几个小时,希望其他人能够通过将所有事情整合在一起来更快地赶上

I've created a custom sub class of TitleView, called CustomTitleView, here's the code:

我创建了一个TitleView名为的自定义子类,CustomTitleView代码如下:

import UIKit

class CustomTitleView: UIView {

  override var intrinsicContentSize: CGSize {
    return UIView.layoutFittingExpandedSize
  }
}

and the most important part which I missed from the start was this:

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

enter image description here

在此处输入图片说明

回答by Jo?o Nunes

Using @falkon's answer here's the code:

使用@falkon's answer这里的代码:

Add this code to the view that is used as titleView

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

override var intrinsicContentSize: CGSize {
    return UILayoutFittingExpandedSize
} 

回答by Alex Kosyakov

Fixed it by creating a subclass of UIView and assigned it to a title view of UINavigationController

通过创建 UIView 的子类并将其分配给 UINavigationController 的标题视图来修复它

Objective-C:

目标-C:

#import "FLWCustomTitleView.h"

@implementation FLWCustomTitleView

- (CGSize )intrinsicContentSize {
  return UILayoutFittingExpandedSize;
}

@end

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明

回答by konradowy

setting intrinsicContentSizeto UILayoutFittingExpandedSizeworks fine as well

设置也intrinsicContentSizeUILayoutFittingExpandedSize正常工作

回答by Yedy

I had to fit an UIImageView as navigationItem.titleView. The aspect ratio did fit but the intrinsicContentSize made it to large. Scaling the image led to poor image quality. Setting layout anchors worked for me:

我必须将 UIImageView 作为 navigationItem.titleView。纵横比确实合适,但 internalContentSize 使它变大。缩放图像导致图像质量不佳。设置布局锚对我有用:

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;

回答by Mischa

Addition to the existing answers:

除了现有答案:

If your custom title view is a view that already has an intrinsic content sizeby default (other than .zero), for example a UILabel, a UITextViewor a UIButton, you can simply set

如果您的自定义标题视图是默认情况下已经具有内在内容大小的视图(除了.zero),例如 a UILabel、 aUITextView或 a UIButton,您可以简单地设置

yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false

and it will automatically adjust to just enclose its contents, but never overlap with the left and right item views.

并且它会自动调整以仅包含其内容,但不会与左右项目视图重叠。



For example, you can drag a button into the title view area of a navigation bar in Interface Builder, create an outlet titleButtonfor it in your view controller and then do

例如,您可以将一个按钮拖到 Interface Builder 中导航栏的标题视图区域,titleButton在您的视图控制器中为其创建一个插座,然后执行

override func viewDidLoad() {
    super.viewDidLoad()
    titleButton.translatesAutoresizingMaskIntoConstraints = false
}

回答by Md. Ibrahim Hassan

Swift 4.2 Version of Yedy's answer

Yedy 答案的Swift 4.2 版本

let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 80, height: 30))
imageView.image = image
imageView.widthAnchor.constraint(equalToConstant: 80).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 30).isActive = true
imageView.contentMode = .scaleAspectFit
navigationItem.titleView = imageView

Converted with the help of Swiftify.

Swiftify的帮助下转换

回答by Suresh Durishetti

When you have a UIView as subview inside CustomTitleView, intrinsicContentSize solution does not work, for me in XCODE 9 in iOS 11 only. so I did like below, works fine for me, might this help someone.

当您在 CustomTitleView 中有一个 UIView 作为子视图时,intrinsicContentSize 解决方案不起作用,仅对我在 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];
    }
}

回答by Qun Li

The most important is that you need overwrite customTitleView as your titleView:

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

self.navigationItem.titleView = [self 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
}

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

回答by hstdt

You can also use constraints if you don't want to override intrinsicContentSize. Here's a demo of SnapKit

如果您不想覆盖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 = ...
}

Butif there are more than one navigationbaritems on any side(left or right) navigationbar, you should use intrinsicContentSize;

但是如果任何一侧(左侧或右侧)导航栏上有多个导航栏项目,则应使用内在内容大小;