Seeing a behavior on iOS11 with a navigationItem.titleView where the width of the titleView is not the full width of the screen.
I have a custom view that I set as t
I had the same issue but with setting an UIImage
as the navigationItem
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;
}
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
Swift 4.2 Version of Yedy's answer
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
Converted with the help of Swiftify.
This class will do the trick. Make sure you set your custom view's class to this one:
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)
}
}
I had to fit an UIImageView as navigationItem.titleView. The aspect ratio did fit but the intrinsicContentSize made it to large. Scaling the image led to poor image quality. Setting layout anchors worked for me:
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;
You can also use constraints if you don't want to override intrinsicContentSize
. Here's a demo of 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 = ...
}
But if there are more than one navigationbaritems on any side(left or right) navigationbar, you should use intrinsicContentSize;