Custom Navigation Bar height is not coming properly - ios

[I have give the Navigation Bar height to 104 but navigation bar item is displaying only till height 44 ]
enter image description here
I cannot post code due to some reason.I am not allow to post the picture also.
My navigation bar item is not display to full height it only comes to up to 44.
For Navigation Bar:
enter code here
let nav = UINavigationbar();
nav.frame = CGRect(x:0,y:0,width:View.frame.width,height:104)
view.addsubview(nav)
Please forgive me for my poor English.

What you can do is to subclass UINavigationBar and use that
class HeightedNavigationBar: UINavigationBar {
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: 104)
}
}

Related

Managing view frame when hide and unhide a tabbar

I have a UIViewController that has tab bar controller at bottom. When user click on a button I m hiding the tab bar. Tab bar is getting hidden but there is a white space at bottom. ViewController frame is not changing. How to manage this ? If tabor controller gets hidden, viewController height should get increase.
func apply(_ effect: ActivityFeedEffect) {
switch effect {
case .feedTypeChange(mode: let mode):
self.parent?.tabBarController?.tabBar.isHidden = mode == .hidden
}
}
This is an extension on UITabBarController, which you can use.
This basically, updates the frames of the view.
You can add animation and other frame handling if needed, based on your use case. But this is something that can lead you in that direction.
extension UITabBarController {
func hideTabBar(isHidden:Bool) {
if (isTabBarAlreadyHidden() == isHidden) { return }
let frame = self.tabBar.frame
let height = frame.size.height
let offsetY = (isHidden ? -height : height)
self.tabBar.frame.offsetBy(dx:0, dy:offsetY)
self.view.frame = CGRect(x:0,y:0,width: self.view.frame.width, height: self.view.frame.height + offsetY)
self.view.setNeedsDisplay()
self.view.layoutIfNeeded()
}
func isTabBarAlreadyHidden() ->Bool {
return self.tabBar.frame.origin.y < UIScreen.main.bounds.height
}
}
In my case, I have configured on the storyboard the extended Edges to go under bottom bars and under opaque bars (see image). So My view always takes the hole screen, and I don't need to adjust the frame. Maybe this helps.
My structure is Tab bar -> Navigation Controller -> TableView (here I hide/show the tab bar)

UISplitViewController: titleView in DetailViewController disappears on landscape orientation, intended behaviour?

I'm adding a custom titleView inside a navigation bar using navigationItem.titleView for both Master/Detail VC. On changing the orientation of the device to landscape, titleView under MasterViewController works fine, but for DetailViewController titleView disappears. On changing the orientation back to portrait titleView appears back for DetailViewController. I have also attached a link for source code and video.
Is this an intended behavior or am I making a mistake from my side or is it an issue from Apple's side ?
//Custom Title View:
class TitleView: UIView {
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: 50, height: 20)
}
}
class DetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Adding titleView for Master/Detail VC:
navigationItem.titleView = {
//Setting frame size here, did not make any difference
let view = TitleView(frame: .zero)
view.backgroundColor = .red
return view
}()
}
}
Full source code here: https://github.com/avitron01/SplitViewControllerIssue/tree/master/MathMonsters
Video highlighting the issue:
https://vimeo.com/336288580
I had the same issue. It seems an iOS bug. My workaround was to reassign the title view on every view layout. I used this piece of code in my DetailViewController:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let v = navigationItem.titleView {
navigationItem.titleView = nil
navigationItem.titleView = v
}
}
For those who stumble upon this, see also iOS 11 navigationItem.titleView Width Not Set. Basically, there's two suggested workarounds:
use a custom UIView that tells iOS to treat its intrinsicContentSize to be as big as possible with UIView.layoutFittingExpandedSize
use widthAnchor/heightAnchor constraints to set width and height of your view

UINavigationBar gets cropped in landscape

I am facing this situation where the navigation bar looks OK in portrait mode but gets cropped in landscape:
portrait
landscape
I subclassed UINavigationBar as follows:
class CustomNavigationBar: UINavigationBar {
override func sizeThatFits(size: CGSize) -> CGSize {
let newSize :CGSize = CGSize(width: self.frame.size.width, height: 64)
return newSize
}
}
and assigned it to the appropriate Navigation Controller via the StoryBoard:
but it makes no difference.
Any ideas?
Navigation bar has different height in Portrait and Landscape mode. You should handle content of custom title view according to navigation bar height. Use autolayout to auto adjust the subview when navigation bar's height changes.
I solved it by overriding sizeThatFits func in an extension. The idea is that it resets the size back to 44 which is the default for portrait:
// prevent navigation bars from resizing in landscape
extension UINavigationBar {
public override func sizeThatFits(size: CGSize) -> CGSize {
let portraitSize = CGSizeMake(UIScreen.mainScreen().bounds.width, 44)
return portraitSize
}
}

iOS - Custom presentation controller doesn't update the presented navigationBar height appropriately for split view

I have created my own subclass of UIPresentationController and I am presenting a navigation controller using it. The purpose is to somewhat mimic the behavior of UIPopoverPresentationController but allow for more customization.
So the problem I am experiencing is that on iPad when the user adjusts the size of the app using splitview, the navigation bar's height doesn't update correctly.
When the view is in a popover style it is supposed to use a height of 44 for the nav bar and when it is in fullscreen style it uses a height of 64. This is happening correctly upon first presenting the controller. However if the user adjusts the app using splitview the nav bar height does not update at all.
In my UIPresentationController subclass I am doing the following:
I set the frame based on the container view's width:
override func frameOfPresentedViewInContainerView() -> CGRect {
if let containerView = containerView {
if containerView.bounds.width > 500 {
let preferredSize = presentedViewController.preferredContentSize
return CGRect(x: containerView.bounds.width - preferredSize.width - 20, y: 16, width: preferredSize.width, height: preferredSize.height)
} else {
return containerView.bounds
}
} else {
return CGRectZero
}
}
Then I update the frame whenever I get the willLayoutSubviews call:
override func containerViewWillLayoutSubviews() {
presentedViewController.view.frame = frameOfPresentedViewInContainerView()
}
When I examine the presentedViewController's view, it is getting all the correct values and visually is the right size. The only problem is that the nav bar will remain the height that it was originally presented at (whether that is 44 or 64) and will either leave a gap or extend passed its bounds.
It appears I found a solution that works. Inside my containerViewWillLayoutSubviews function I simply access the navigation controller's navigationBar property and manually set its frame correctly.
if let navigationController = presentedViewController as? UINavigationController {
navigationController.navigationBar.frame = CGRect(x: 0,
y: 0,
width: presentedViewController.view.frame.size.width,
height: containerView.bounds.width > 500 ? 44 : 64)
}
This does seem a bit fragile though, but its working fine for me.

Move Tab Bar to top of screen

I have a Tab Bar Controller which, as we know, displays the tab bar at the bottom of the screen. I'm looking for a way to move it to the top. I don't think I can use a simple UITabBar for this as I need to nest UINavigationControllers under it.
Is there any way to move the Tab Bar in a UITabBarController to the top of the screen?
Try this code in methods "viewDidLayoutSubviews" your UITabBarController
Swift 2.X
self.tabBar.frame = CGRectMake(0,0,320,50) //example for iPhone 5
Swift 3.X
self.tabBar.frame = CGRect(0,0,320,50) //example for iPhone 5
Swift 4.X
self.tabBar.frame = CGRect( x: 0, y: 0, width: 320, height: 50) //example for iPhone 5
(in Swift)
In the TabBarViewController.swift file (everyone has named this file as he wants):
First: create an IBOutlet of a tab bar and then connect it to the appropiate tab bar in the storyboard or in the nib file.
#IBOutlet var profileTabBar : UITabBar!
Second: add this code in the viewDidLoad() function to situate the tab bar where you want (in this case I add de tab bar under the navigation controller). To modify the position change x and y of CGRectMake initializer.
// [Maybe you don't have a navigation controller] yNavBar indicates the height of the navigation bar.
var yNavBar = self.navigationController?.navigationBar.frame.size.height
// yStatusBar indicates the height of the status bar
var yStatusBar = UIApplication.sharedApplication().statusBarFrame.size.height
// Set the size and the position in the screen of the tab bar
profileTabBar.frame = CGRectMake(0, yNavBar! + yStatusBar + profileTabBar.frame.size.height, profileTabBar.frame.size.width, profileTabBar.frame.size.height)
I dont think so. The only thing I can think of is to use UITabBar instead of UITabbarController ...
This might be a better option anyway if you are considering nesting UINavigationControllers for each view loaded for the different tabs.
in the viewDidLayoutSubviews() put this code like this
override func viewDidLayoutSubviews() {
tabBar.frame = CGRect(x: 0,y: 0,width: UIScreen.main.bounds.width,height: 30)
}
I use Tab Bar Controller then I simply change the TabBar position in the Tab Bar Controller in the ViewDidLoad()
import UIKit
class TabbarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.frame = CGRect(origin: CGPoint(x: 0,y :64), size: CGSize(width: 400, height: 50))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is the Screen Short attached of the required result...
Tab bar on top in tab bar view conmtroller
Note: It is in swift 3 you can change the syntax to swift 2.* on your own.

Resources