web-dev-qa-db-de.com

iOS 11 navigationItem.titleView Width Nicht festgelegt

Anzeigen eines Verhaltens unter iOS11 mit einer navigationItem.titleView, wobei die Breite der titleView nicht die gesamte Bildschirmbreite ist.

Ich habe eine benutzerdefinierte Ansicht, die ich als Titelansicht eingestellt habe. Vor iOS11 füllte die Ansicht den Navigationsleistenbereich aus. Bei iOS 11 wird jedoch die Größe des Bildschirms nicht geändert.

Ich habe versucht, den Rahmen der Ansicht einzustellen, bevor Sie titleView setzen, aber kein Glück. Ich habe versucht, den titleViews-Überblick auch zu Layout-Einschränkungen zu zwingen, aber kein Glück. 

Angehängte Screenshots:

iOS10:

 enter image description here

iOS11:

 enter image description here

Jemand anderes erlebt das?

52
gngrwzrd

Ich habe es herausgefunden. Ich musste den intrinsicContentSize-Getter für die Ansicht und das Textfeld überschreiben.

Ich habe die Breite auf CGFloat.greatestFiniteMagnitude gesetzt, damit sie immer so breit ist wie der Bildschirm.

Update:

Da ich einige Stunden mit diesem Thema verbracht habe, hoffe ich, dass einige andere schneller aufholen werden, wenn alle Dinge eng zusammen sind

Ich habe eine benutzerdefinierte Unterklasse von TitleView mit dem Namen CustomTitleView erstellt. Hier ist der Code:

import UIKit

class CustomTitleView: UIView {

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

und der wichtigste Teil, den ich von Anfang an vermisst habe, war Folgendes:

 enter image description here

89
gngrwzrd

Mit der Antwort von @falkon hier der Code:

Fügen Sie diesen Code der Ansicht hinzu, die als Titelansicht verwendet wird

override var intrinsicContentSize: CGSize {
    return UILayoutFittingExpandedSize
} 
37
João Nunes

Behebung des Problems durch Erstellen einer Unterklasse von UIView und Zuweisung einer Titelansicht von UINavigationController

Ziel c:

#import "FLWCustomTitleView.h"

@implementation FLWCustomTitleView

- (CGSize )intrinsicContentSize {
  return UILayoutFittingExpandedSize;
}

@end

 enter image description here  enter image description here

14
Alex Kosyakov

die Einstellung von intrinsicContentSize auf UILayoutFittingExpandedSize funktioniert ebenfalls gut

12
konradowy

Ich musste eine UIImageView als navigationItem.titleView einbauen. Das Seitenverhältnis passte zwar, aber mit intrinsicContentSize wurde es zu groß. Die Skalierung des Bildes führte zu einer schlechten Bildqualität.

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;
6
Yedy

Das Wichtigste ist, dass Sie customTitleView als titleView überschreiben müssen:

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

2
Qun Li

Wenn Sie eine UIView als Unteransicht in CustomTitleView haben, funktioniert die intrinsicContentSize-Lösung nicht, nur für XCODE 9 in iOS 11. also ich habe unten gerne, funktioniert gut für mich, könnte das jemandem helfen. 

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

Sie können Einschränkungen auch verwenden, wenn Sie intrinsicContentSize nicht überschreiben möchten. Hier ist eine Demo von 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 = ...
}

Aber Wenn sich auf einer beliebigen (linken oder rechten) Navigationsleiste mehr als eine Navigationsleiste befindet, sollten Sie intrinsicContentSize verwenden.

1
hstdt

Ich hatte das gleiche Problem, hatte aber eine UIImage als navigationItemtitleView

Was ich getan habe, ist, dass ich das Bild auf die benötigte Größe skaliert habe, indem ich folgendes verwendet:

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

Und nenne es wie folgt:

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

return UILayoutFittingExpandedSize hat mir nicht geholfen, da die Ansicht einige Male vertikal hinzugefügt wurde, um das Layout zu füllen.

Die Lösung bestand darin, intrinsicContentSize in der benutzerdefinierten Ansicht außer Kraft zu setzen, um die Breite auf die maximale Bildschirmbreite einzustellen:

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

Versuchen Sie es mit dem Standard UISearchBar/UISearchController.

Eigentlich müssen Sie - wenn Sie eine Standard-UISearchBar/einen UISearchController verwenden können - die Suchleiste auf folgende Weise anzeigen, die den sicheren Bereich berücksichtigt und auf dem iPhone X und in jeder Geräteorientierung perfekt aussieht:

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

Verweise

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

0
blackjacx

Ergänzung zu den vorhandenen Antworten:

Wenn Ihre benutzerdefinierte Titelansicht eine Ansicht ist die bereits eine eigene Inhaltsgröße hat standardmäßig (außer .zero), zum Beispiel a UILabel, a UITextView oder a UIButton können Sie einfach einstellen

yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false

und es passt sich automatisch an, um nur seinen Inhalt einzuschließen, überschneidet sich jedoch nie mit der linken und rechten Elementansicht.


Sie können beispielsweise eine Schaltfläche in den Titelansichtsbereich einer Navigationsleiste in Interface Builder ziehen, einen Ausgang titleButton für sie in Ihrem Ansichtscontroller erstellen und dann ausführen

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

Swift 4.2 Version von Yedys Antwort

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

Konvertiert mit Hilfe von Swiftify .

0