![](/img/trans.png)
[英]UITapGestureRecognizer on navigationItem.titleView not working on iOS 11
[英]iOS 11 navigationItem.titleView Width Not Set
我想到了。 我必須覆蓋視圖和文本字段的 intrinsicContentSize getter。
我將寬度設置為 CGFloat.greatestFiniteMagnitude 所以它總是和屏幕一樣寬。
更新:
因為我在這個問題上花了幾個小時,希望其他人能通過把所有事情都緊密地放在一起來更快地趕上
我創建了TitleView
的自定義子類,稱為CustomTitleView
,代碼如下:
import UIKit
class CustomTitleView: UIView {
override var intrinsicContentSize: CGSize {
return UIView.layoutFittingExpandedSize
}
}
我從一開始就錯過的最重要的部分是:
使用@falkon 的答案是代碼:
將此代碼添加到用作 titleView 的視圖
override var intrinsicContentSize: CGSize {
return UILayoutFittingExpandedSize
}
將intrinsicContentSize
設置為UILayoutFittingExpandedSize
也可以正常工作
我必須將 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;
如果您的自定義標題視圖是默認情況下已經具有固有內容大小的視圖(除了.zero
),例如UILabel
、 UITextView
或UIButton
,您可以簡單地設置
yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false
並且它會自動調整以僅包含其內容,但不會與左右項目視圖重疊。
例如,您可以將一個按鈕拖到 Interface Builder 中導航欄的標題視圖區域,在您的視圖控制器中為它創建一個插座titleButton
然后執行
override func viewDidLoad() {
super.viewDidLoad()
titleButton.translatesAutoresizingMaskIntoConstraints = false
}
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
在Swiftify的幫助下轉換。
最重要的是你需要覆蓋 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
}
當您在 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];
}
}
這個類會做的伎倆。 確保將自定義視圖的類設置為此:
import UIKit
class TitleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
super.init(coder: coder)
translatesAutoresizingMaskIntoConstraints = false
}
override var intrinsicContentSize: CGSize {
CGSize(width: UIView.layoutFittingExpandedSize.width, height: self.bounds.height)
}
}
如果您不想覆蓋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;
}
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;
}
嘗試使用標准 UISearchBar / UISearchController
實際上你需要做的 - 如果你可以使用標准的 UISearchBar / 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
在設置您的導航控制器時
您所要做的就是將 translatesAutoresizingMaskIntoConstraints 設置為 false check apple doc
請注意,自動調整掩碼約束完全指定了視圖的大小和位置; 因此,您不能在不引入沖突的情況下添加額外的約束來修改此大小或位置。 如果你想使用自動布局來動態計算視圖的大小和位置,你必須將這個屬性設置為 false
然后將它分配給你想要的寬度
navigationItem.titleView?.translatesAutoresizingMaskIntoConstraints = false
lazy var titleWidth = view.frame.size.width / 2
navigationItem.titleView?.constrainWidth(constant: titleWidth)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.