42

在iOS11上使用navigationItem.titleView查看行爲,其中titleView的寬度不是屏幕的整個寬度。iOS 11 navigationItem.titleView寬度未設置

我有一個自定義視圖,我設置爲titleView。在iOS11之前,視圖將填充導航欄區域。但是iOS 11並沒有調整屏幕寬度。

我試着在設置titleView之前設置視圖的框架,但沒有運氣。我試圖強制titleViews superview佈局約束,但沒有運氣。

截圖附:

iOS10:

enter image description here

iOS11:

enter image description here

任何人的經驗呢?

回答

63

我想通了。我不得不重寫視圖的intrinsicContentSize getter和文本字段。

我將寬度設置爲CGFloat.greatestFiniteMagnitude,以便它始終與屏幕一樣寬。

更新:

既然我已經花了幾個小時,在這個問題上,希望有些人會更快地趕上通過使所有的東西緊在一起

我創建一個自定義子一流的TitleView,叫CustomTitleView,下面的代碼:

import UIKit 

class CustomTitleView: UIView { 

    override var intrinsicContentSize: CGSize { 
    return UILayoutFittingExpandedSize 
    } 
} 

和我從一開始就錯過了最重要的部分是這樣的:

enter image description here

+3

作爲一個解釋:titleview的現在擺好了自動佈局。由於它尋找intrinsicContentSize,所以這是有效的。 – mangerlahn

+0

可以在大標題視圖下方顯示標題視圖嗎?我爲title視圖分配了一個segmentedControl,並且它總是顯示大標題。 – Arco

+0

謝謝!這解決了我的問題。 – rilar

11

設置intrinsicContentSizeUILayoutFittingExpandedSize正常工作以及

+1

這是正確的答案 –

31

這裏使用@ falkon的回答是代碼:

這個代碼添加到用作titleview的

override var intrinsicContentSize: CGSize { 
    return UILayoutFittingExpandedSize 
} 
+0

完美。那確實解決了這個問題。謝謝! – BEm

+0

已修復,但有時標題視圖將在使用動畫後在狀態欄下移動。 – Lumialxk

+0

我還必須在該視圖中添加'translatesAutoresizingMaskIntoConstraints = false'。 – rafalkitta

0
視圖

我有同樣的問題,但設置UIImage作爲navigationItemtitleView

我所做的是我通過使用下面的縮放圖像所需的大小:

-(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; 
} 
2

最重要的是,你需要重寫customTitleView as your 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

10

通過創建的UIView的子類的固定並將其分配到導航控制器的標題視圖

Objectve-C:

#import "FLWCustomTitleView.h" 

@implementation FLWCustomTitleView 

- (CGSize)intrinsicContentSize { 
    return UILayoutFittingExpandedSize; 
} 

@end 

enter image description here enter image description here

1

您也可以使用約束,如果你不希望覆蓋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多個navigationbaritems;

+0

你知道爲什麼需要少於44嗎?我嘗試做大而沒有成功。 –

1

當您在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]; 
    } 
} 
0

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; 
} 
4

我不得不適應一個的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; 
0

嘗試使用標準的UISearchBar/UISearchController

其實你需要做什麼 - 如果你可以使用一個標準的UISearchBar/A UISearchController是顯示搜索酒吧,尊重安全區下面的方式,因此看起來完美的iPhone X和每個設備的方向:

func presentSearchController() { 
    let searchController = UISearchController(searchResultsController: nil) 
    searchController.searchResultsUpdater = self 
    searchController.obscuresBackgroundDuringPresentation = false 
    searchController.searchBar.text = "any text" 

    if #available(iOS 11.0, *) { 
     self.navigationItem.searchController = searchController 
     searchController.isActive = true 
    } else { 
     present(searchController, animated: true, completion: nil) 
    } 
} 

個參考

https://developer.apple.com/videos/play/fall2017/201/ https://medium.com/@PavelGnatyuk/large-title-and-search-in-ios-11-514d5e020cee