IT Share you

iOS 11 navigationItem.titleView 너비가 설정되지 않음

shareyou 2020. 12. 2. 22:15
반응형

iOS 11 navigationItem.titleView 너비가 설정되지 않음


titleView의 너비가 화면의 전체 너비가 아닌 navigationItem.titleView를 사용하여 iOS11에서 동작을 확인합니다.

titleView로 설정 한 사용자 정의보기가 있습니다. iOS11 이전에는보기가 탐색 모음 영역을 채웠습니다. 그러나 iOS 11은 화면 너비를 채우기 위해 크기가 조정되지 않습니다.

titleView를 설정하기 전에 뷰의 프레임을 설정하려고 시도했지만 운이 없습니다. titleViews superview를 레이아웃 제약 조건으로 강제하려고 시도했지만 운이 없습니다.

첨부 된 스크린 샷 :

iOS10 :

여기에 이미지 설명 입력

iOS11 :

여기에 이미지 설명 입력

다른 사람이 이것을 경험합니까?


나는 그것을 알아. 뷰와 텍스트 필드에 대한 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
} 

UIView의 하위 클래스를 만들고 UINavigationController의 제목보기에 할당하여 수정했습니다.

목표 -C :

#import "FLWCustomTitleView.h"

@implementation FLWCustomTitleView

- (CGSize )intrinsicContentSize {
  return UILayoutFittingExpandedSize;
}

@end

여기에 이미지 설명 입력 여기에 이미지 설명 입력


잘 작동 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;

가장 중요한 것은 customTitleView를 titleView로 덮어 써야한다는 것입니다.

self.navigationItem.titleView = [자기 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가있는 경우 iOS 11의 XCODE 9에서만 intrinsicContentSize 솔루션이 작동하지 않습니다. 그래서 나는 아래와 같이했고, 나를 위해 잘 작동하며, 이것이 누군가를 도울 수 있습니다.

@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];
    }
}

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 의 도움으로 변환되었습니다 .


재정의하지 않으려면 제약 조건을 사용할 수도 있습니다 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는 ASnavigationItem titleView

What i did is i scaled the image to the needed size by using the below:

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

And call it as follows:

-(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 not helped me, because view was added vertically few more times to fill layout.

The solution was to override intrinsicContentSize in custom view setting width to max screen width:

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

Try using the Standard UISearchBar / UISearchController

Actually what you need to do - if you can use a standard UISearchBar / a UISearchController is to display the search bar the following way which respects the safe area and thus looks perfect on iPhone X and in each device orientation:

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)
    }
}

References

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


Addition to the existing answers:

사용자 지정 제목보기가 기본적으로 기본 콘텐츠 크기 (제외 .zero) 가 이미 있는보기 ( 예 : a UILabel, a UITextView또는 a) 인 UIButton경우 간단히 설정할 수 있습니다.

yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false

내용을 묶기 위해 자동으로 조정되지만 왼쪽 및 오른쪽 항목보기와 겹치지 않습니다.


예를 들어, Interface Builder에서 탐색 모음의 제목보기 영역으로 버튼을 드래그하고 titleButton보기 컨트롤러에서 해당 콘센트 를 만든 다음

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

참고 URL : https://stackoverflow.com/questions/44932084/ios-11-navigationitem-titleview-width-not-set

반응형