Voir un comportement sur iOS11 avec un objet navigationItem.titleView où la largeur de titleView n'est pas la largeur totale de l'écran.
J'ai une vue personnalisée que j'ai définie comme titleView. Avant iOS11, la vue remplissait la zone de la barre de navigation. Mais iOS 11 n’est pas en train de redimensionner pour remplir la largeur de l’écran.
J'ai essayé de définir le cadre de la vue avant de définir titleView, mais sans succès. J'ai essayé de forcer le titleViews superview aux contraintes de mise en page, mais pas de chance.
Captures d'écran ci-joint:
iOS10:
iOS11:
Quelqu'un d'autre en fait l'expérience?
Je l'ai compris. J'ai dû remplacer le getter intrinsicContentSize pour la vue et le champ de texte.
J'ai défini la largeur sur CGFloat.greatestFiniteMagnitude afin qu'elle soit toujours aussi large que l'écran.
Mettre à jour:
Depuis que j'ai passé quelques heures sur cette question, j'espère que d'autres parviendront à se rattraper plus rapidement en rapprochant tout
J'ai créé une sous-classe personnalisée de TitleView
, appelée CustomTitleView
, voici le code:
import UIKit
class CustomTitleView: UIView {
override var intrinsicContentSize: CGSize {
return UIView.layoutFittingExpandedSize
}
}
et la partie la plus importante que j'ai manquée dès le début était la suivante:
En utilisant la réponse de @ falkon, voici le code:
Ajouter ce code à la vue utilisée comme titleView
override var intrinsicContentSize: CGSize {
return UILayoutFittingExpandedSize
}
régler intrinsicContentSize
sur UILayoutFittingExpandedSize
fonctionne aussi très bien
Je devais adapter un UIImageView en tant que navigationItem.titleView. Le rapport de format était correct, mais la taille intrinsèque de ContentSize le rendait trop volumineux. La mise à l'échelle de l'image entraînait une qualité d'image médiocre.
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;
Le plus important est que vous devez écraser customTitleView en tant que titleView:
self.navigationItem.titleView = [auto 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
}
Lorsque vous avez une vue UIView en tant que sous-vue dans CustomTitleView, la solution intrinsicContentSize ne fonctionne pas. Pour moi, dans XCODE 9 sous iOS 11 uniquement. donc j'ai aimé comme ci-dessous, fonctionne bien pour moi, cela pourrait-il aider quelqu'un.
@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];
}
}
Vous pouvez également utiliser des contraintes si vous ne souhaitez pas remplacer intrinsicContentSize
. Voici une démo de 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 = ...
}
Mais s'il y a plus d'une barre de navigation sur l'un des côtés (gauche ou droite), vous devez utiliser intrinsicContentSize;
J'ai eu le même problème, mais avec la définition d'une UIImage
comme navigationItem
titleView
Ce que j'ai fait est que j'ai redimensionné l'image à la taille souhaitée en utilisant les éléments suivants:
-(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;
}
Et appelez-le comme suit:
-(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
ne m'a pas aidé, car la vue a été ajoutée verticalement plusieurs fois pour remplir la présentation.
La solution consistait à remplacer intrinsicContentSize
dans la largeur de la vue personnalisée en définissant la largeur maximale de l'écran:
- (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;
}
Essayez d'utiliser le standard UISearchBar/UISearchController
En fait, ce que vous devez faire - si vous pouvez utiliser un UISearchBar/un UISearchController standard, c’est d’afficher la barre de recherche de la manière suivante, qui respecte la zone de sécurité et est donc parfaite sur iPhone X et dans chaque orientation de périphérique:
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)
}
}
Références
https://developer.Apple.com/videos/play/fall2017/201/https://medium.com/@PavelGnatyuk/large-title-and-search-in-ios- 11-514d5e020cee
Si votre vue de titre personnalisée est une vue qui a déjà une taille de contenu intrinsèque par défaut (autre que .zero
), par exemple une UILabel
, une UITextView
ou une UIButton
, vous pouvez simplement mettre
yourCustomTitleView.translatesAutoresizingMaskIntoConstraints = false
et il s'ajustera automatiquement pour ne contenir que son contenu, mais ne chevauchera jamais les vues d'élément gauche et droite.
Par exemple, vous pouvez faire glisser un bouton dans la zone d'affichage du titre d'une barre de navigation dans Interface Builder, créer un point de vente titleButton
dans votre contrôleur de vue, puis effectuer les opérations suivantes:
override func viewDidLoad() {
super.viewDidLoad()
titleButton.translatesAutoresizingMaskIntoConstraints = false
}
Swift 4.2 Version de Réponse de Yedy
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
Converti à l'aide de Swiftify .