Bar section in iOS is extended unnecessarily - ios

In the image shared, the orange section is the bar section , which is having unnecessary height, I am not able to resolve this issue by myself.
the views are like this
Parent Controller = View Controller
Child views = green view, black tableview
Please help to correct the height of the orange bar.

Seems like you have enabled prefersLargeTitles.
Make it false in your viewWillAppear()
self.navigationController?.navigationBar.prefersLargeTitles = false
You can also disable it from the storyboard.
Select your Navigation Controller -> Navigation Bar -> Uncheck prefers large titles

it seems like you're using the largeTitles on the navigationBar,
var prefersLargeTitles: Bool { get set }
When this property is set to true, the navigation bar allows the
title to be displayed out-of-line and using a larger font. The
navigation item used to build the bar must specify whether it wants
its title displayed in the large or small format. Use the
largeTitleDisplayMode property to configure the title's appearance.
When the property is set to false, the navigation bar displays the
title inline with the other bar button items.
try to disable it by:
navigationController?.navigationBar.prefersLargeTitles = false
or you can do this as well:
navigationItem.largeTitleDisplayMode = .never
hope this helps:)
https://developer.apple.com/documentation/uikit/uinavigationbar/2908999-preferslargetitles

Related

Content under UINavigationBar & UITabBar

I have a UINavigationController embedded inside a UITabBarController.
The problem is that my content always appears underneath the bars. I have a collection view with x & y set to 0 which appears fine. The green view however is just a simple UIView with the same x & y positions.
My question is, how can I make the content properly show at the expected y coordinate of 0?
Set the isTranslucent property to false on both the navigation bar and the tab bar.
For the nav bar:
navigationController.navigationBar.isTranslucent = false
For the tab bar:
tabBarController.tabBar.isTranslucent = false
Where you do this will depend on how your code is structured, but the easiest spot for each will likely be right after you initialize the tab bar controller and the navigation controller.

iOS 11 prefersLargeTitles with uibutton as title

As titled, I'm using a UIButton as the titleView in the navbar. Is there a way for me to make the UIButton larger along with the navbar? When I set self.navigationController?.navigationBar.prefersLargeTitles = true, what I got is this,
I can't find any documentation on this, so I played a bit. It seems in iOS 11, you won't be able to get that title to be a button and display large at the left.
Also, I ttied playing with the frame size of the button (added below). I was unable to increase the button size, no matter what I set the frame to.
To recreate, I set up a Single View project. I embedded the view controller in a navigation controller.
In ViewController.swift's viewDidLoad, I added this code:
let titleButton = UIButton(type: .roundedRect)
titleButton.setTitle("Hello Button!", for: UIControlState.normal)
let navController = parent as! UINavigationController
navController.navigationBar.topItem!.title = "Hello???"
navController.navigationBar.topItem!.titleView = titleButton
navController.navigationBar.prefersLargeTitles = true
This ends up looking something like your example.
IF I:
set .title to empty string, or remark the line out: navbar is stretched, and no title text shows (or title text set in Interface Builder shows)
remark out .prefersLargeTitles, or set it to false: the navbar is the normal height, the button displays, but no title text displays.
remark out the titleView line, AND:
leave the .prefersLargeTitles set to true: the title text displays large at the left, and the navbar's height is stretched.
set the .prefersLargeTitles to false: the title text displays in the top center, and the navbar is normal height.

Search bar as header in tableview - appear and disappear

I need to put a search bar at the top of my tableview. I am making a network call and when the results are greater than 100 I want to search bar to appear and when they are less than 100 I don't want to search bar to appear. The tableview is on the right side of the VC and does not take up the whole view controller. I want the search bar to be at the top of the table view as a header.
I cannot use a search controller because in iOS 11, using a search controller makes the search bar pop to the top of the VC when it is active.
I tried to set the tableviewheader to nil to get it to disappear. But I can't get it back obviously because I made the header nil.
self.rightDetailFilterTableView.tableHeaderView = nil
self.rightDetailFilterTableView.sectionHeaderHeight = 0
I have put the search bar into the storyboard as seen in the image below. Is this the right way to add the search bar as a header?
What is the best way to get it to appear and disappear in the tableview? I have tried a bunch of different methods. They all either leave a blank header or do something else that causes problems. I also tried using the header delegate methods but that still did not work.
I am not using a tableview controller, I am using a normal VC. I am also not using a search bar controller because of issues it causes in iOS 11.
Here's what I've done in one of my recent project. First, laid out my views like so:
That is, the Search Bar was added to the parent view rather than the table view. This allows me to hide/show it as needed.
Next, I've defined two optional layout constraint, one ensuring that the tableview is aligned to the top of the safe area, priority 750; the other aligning the top of the search bar to the top of the safe area; priority lower than 750 to hide it below the nav bar or priority higher than 750 to reveal it and push the table view down.
In code, I created a #IBOutlet to the layout constraint for the search bar to the top of the safe area, and I change its priority as needed:
#IBAction
func toggleSearchBar(_ sender: Any?) {
if searchBarVisibleLayoutConstraint.priority.rawValue > 750.0 {
searchBarVisibleLayoutConstraint.priority = UILayoutPriority(rawValue: 1.0)
searchBar?.endEditing(true)
} else {
searchBarVisibleLayoutConstraint.priority = UILayoutPriority(rawValue: 999.0)
}
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
In my case, the navigation bar is opaque and the search bar is not visible behind it. Your case may be different so you may also want to either clip the parent view or alpha fade the search bar when it is not visible.
Good luck!
Please check :
Created IBOutlet for my SearchBar.
#IBOutlet weak var testbar: UISearchBar!
And in my viewDidLoad :
override func viewDidLoad() {
var contentOffset = tableView.contentOffset
let showSearchBar = (results.count > 100)
self.tableView.tableHeaderView?.isHidden = !(showSearchBar)
if showSearchBar {
contentOffset.y -= testbar.frame.size.height
} else {
contentOffset.y += testbar.frame.size.height
}
tableView.contentOffset = contentOffset
}
Here is my tableview storyboard

Custom title view as large title in iOS 11 new navigation bar

I am using a button as a title view for my UITableViewController which opens a dropdown list of categories. Selecting a category filters content of the table view by the selected category.
The button shows the name of the selected category plus a small arrow, similar to how iBooks used to look (or maybe still looks? I haven't used it in a while). I would therefore like it to have the same behaviour as a standard title and have it be large at first and collapse when the table view is scrolled.
Is there a way to do this?
Thanks
It seems because of the new large titles, IOS11 requires the constraints on the custom view in the navigationItem.titleView to be set.
Do this for example:
customView.widthAnchor.constraint(equalToConstant: 200).isActive = true
customView.heightAnchor.constraint(equalToConstant: 44).isActive = true
self.navigationItem.titleView = customView
Note this must be done for both width and height.
It should work. No need to add a button, at least in my case...
This was suggested by Apple to ensure that you don't have zero-size custom views. See slide 33 in https://developer.apple.com/videos/play/wwdc2017/204/
Looks like touches are broken for navigationItem.titleView. Gestures, tap events and buttons - nothing works
Seems like a bug in iOS 11: https://forums.developer.apple.com/thread/82466
I provisionally implemented this workaround:
private lazy var navBarActionButtonIOS11: UIButton = {
button.addTarget(self.navTitleView, action: #selector(self.navTitleView.didTapView), for: .touchUpInside)
return button
}()
[...]
navigationItem.titleView = navTitleView
if #available(iOS 11.0, *), let navBar = navigationController?.navigationBar {
navBarActionButtonIOS11.removeFromSuperview()
navBar.addSubview(navBarActionButtonIOS11)
navBarActionButtonIOS11.center.x = navBar.center.x
}
Another solution could be to just assign a UIButton to navigationItem.titleView directly.
I hope Apple fixes this soon!
Well, I had same problem. I have UIButtons in UINavigationItem.titleView and those were not reacting to touches at all. Problem is that the view where those buttons are where of size (0,0) because of auto layout. So to fix this problem you need to add additional view into your custom view, lets call it "contentView" and put all your controls inside that contentView. Also, contentView must have defined size with constraints. Quick test is to add width and height constraint to contentView. And all works again.
Hope that this helps someone.

Custom modal window with image in header

i would ask if it is possible to change to base modal window to look like my image? (only layout test)
I can easiliy set up an image with:
var barButtonImage:UIImage = UIImage(named: "header_test.png")
var barButtonImageView = UIImageView(image: barButtonImage)
self.navigationItem.titleView = barButtonImageView
But i am not able to set it outside the view - is that possible? And if, how?
EDIT:
Thanks for the info about using clipsToBounds. I set it to titleview and bar to false, but the image is not outside the modal (but it is over the top of my UITableView in the modal window)
self.navigationItem.titleView.clipsToBounds = false
self.navigationController.navigationBar.clipsToBounds = false
You're going to have to embed your visual stuff inside another view, with that view's background set to transparent.
Or, you could play around with the "clips subviews" property of your view, to allow the round graphic to not get clipped at the edges of the superview that contains it.

Resources