How to overlap navigation bar by adding view in swift? - ios

I want to make a custom side bar by adding a new view to the view controller, the side bar will be in the yellow color background. I want my side bar also to overlap the navigation bar/item (green background color) in my view controller. but the navigation bar/item seems can't be overlapped by my side bar view, it seems only overlap the main view.
I tried to find the answer in stackoverflow, I find this Overlap navigation bar on ios 6 with other view, but the answer is on the Objective-C, I can't read Objective-C :(
What should I do to overlap navigation bar/item ? here is the screenshot of my view controller
I embed the navigation controller like this

There are plenty of implementations of slide-over or drawer containers.
What you need to do to get above the navigation bar is CONTAIN the navigation controller inside another view controller.
The stack would look like this.
MasterViewController
UINavigationController
RootViewController
Menu
See this one here:
Swift version of MMDrawerController

You can do this by changing your UIViewController hierarchy. For this you'll need three view controllers. First will contain everything, let's call it MasterViewController; second—your main content with navigation bar; and third—drawer.
In MasterViewController instantiate child view controllers and add them to your view controller hierarchy in viewDidLoad().
final class MasterViewController: UIViewController {
override func viewDidLoad() {
let drawerViewController = DrawerViewController()
let mainViewController = MainContentViewController()
let navigationController = UINavigationController(rootViewController: mainViewController)
addChildViewController(drawerViewController)
addChildViewController(navigationController)
view.addSubview(navigationController.view)
view.addSubview(drawerViewController.view)
}
}
Now you have navigationController.view that you can place or animate anywhere within view.

Related

What is best approach to creating a persistant UIView nav bar in a UITabBarController?

I've added a custom UIView to my base UITabBarController. I start by hiding the default tabBar. The viewdidload looks like this in UITabBarController:
override func viewDidLoad() {
super.viewDidLoad()
//hide default tab bar
self.tabBar.isHidden = true
tabBarArea.frame.size.width = self.view.frame.width
tabBarArea.frame.origin.y = self.view.frame.height - tabBarArea.frame.height
self.view.addSubview(tabBarArea)
}
That works well. The tabBarArea is defined in the storyboard as a custom view for the UITabBarController. The custom view sits between the First Responder and the Exit icons in the top bar.
Now, the problem is that the UITabBarController will disappear as soon as we load a child view controller and this custom UIView area will vanish with it.
Is there a way to make this root custom view always present even when child view controllers are loaded in?
Thanks for input. I like the idea of this custom UIView area but this approach needs refinement. I also don't need it to be a traditional UITabBarController with tab bar items, etc. I'd like to break out of that mold and just have custom UIButtons are whatever in this view area.

Fixed Navigation Bar For Different View Controllers

I am trying to implement a navigation bar whose contents persist between different view controllers. For example, I have the following functionality right now:
Non Persistent Navigation Bar
I have set an imageView as the titleView of the navigation bar.
The titleView of the navigation bar transitions along with the view controller here (the image shows some animations by fading in and out). But I would like it to stay hooked onto the top of every screen without any transitions. This would mean that only the part of the view below the navigation bar would show the transition from one view controller to another.
Is that possible in Swift?
Yea that is possible. What you can do is have a container view controller, which can have your navigation bar along with a content view controller.
Now each time you open a new VC, push the new VC on the containerVC's contentVC.
For ex:
let containerVC = self.parentViewController?.containerViewController()
if let _ = containerVC {
containerVC.pushContentViewController(newViewController)
}
Attaching layout screenshot for more understanding.
So if you check here, the Root Container is the view where you can add your new VC as a child VC.
You can do this by changing your UIViewController hierarchy. For this you'll need three view controllers. First will own your UINavigationBar and UIView where other two UIViewController's views will live.
Let's call one with the navigation bar MasterViewController, and other two—ViewControllerA, ViewControllerB respectively.
Somewhere in MasterViewController instantiate child view controllers and add them to your view controller hierarchy. For simplicity's sake let's do everything in viewDidLoad() but you can do do this anywhere you deem it necessary. You could even load view controllers lazily as user demands them.
final class ViewControllerA: UIViewController { }
final class ViewControllerB: UIViewController { }
final class MasterViewController: UIViewController {
var navigationBar = UINavigationBar()
override func viewDidLoad() {
view.addSubview(navigationBar)
let a = ViewControllerA()
let b = ViewControllerB()
addChildViewController(a)
addChildViewController(b)
view.addSubview(a.view)
// you are ready for transitions from a.view to b.view when necessary
}
}
Now you can do transitions from a.view to b.view (and back) and it will affect nothing in master view (which has the navigationBar).
It is important to note that view hierarchy and view controller hierarchy are not liked in any way and you are responsible for managing both.

Swift: present view controller in same context as other view controllers?

Ok, I have an issue that I cant understand trying to present a view controller (the same instance every time, just like other tab item VCs) from an overall tab bar controller VC. My tab bar controller VC has 3 view controllers that it is connected to via storyboard, so 3 tab bar items appear on the tab bar. When the selectedIndex is changed, these view controllers just appear right there below the subviews of the Tab Bar Controller VC.
These subviews that should always be on top are the nav bar at the top and tab bar at bottom:
And this is great for those 3 view controllers. Problem is I need to access 1 instance of ANOTHER view controller that is NOT shown in the tab bar buttons via a button in the nav bar here.
My problem is no matter how I present it, this VC always pops OVER the tab bar controller VC, covering the tab bar and nav bar.
here I make sure only 1 instance is made:
if podcastVC == nil {
//print("IT IS NIL")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
podcastVC = storyboard.instantiateViewController(withIdentifier: "podcast") as! PodcastViewController
//*NOTE: have to set other vars too, this is temp
podcastVC.urlStr = currentTrackUrl!
podcastVC.originalUrl = currentTrackUrl!
AudioPlayerManager.shared.play(urlString: podcastVC.urlStr)
}
self.show(podcastVC, sender: self)
podcastVC.modalPresentationStyle = .currentContext
podcastVC.definesPresentationContext = false
[1]: https://i.stack.imgur.com/1d6MZ.png
as shown by Swift: How to return to the same instance of my UIViewController
How can I make that VC present in the same context as the tab bar items? I have tried setting the layer of the nav bar to a z position much higher (like 10) but nothing works. What is wrong?
Modal view :
Can works for all view controllers
Is over all other view and need to be pop programatically (adding a button back manually for example)
Push View :
Only works in navigation controllers
Add automatically a back button in the navigationController
you should push VC and it will keep tabbar and nav
you can change modal present style

In Swift, I have 2 navigation bars but want to hide one of them, how to do it?

I currently have a viewcontroller that has two navigation bars because Its has a navigation controller both before and after a tab bar controller. I tried to have it so that the viewcontroller before the tab bar controller will present modally but by dong so the 2nd nav bar didn't work properly. The 2nd nav bar is a custom side menu that only appears to work if the first navigation controller is preset. Here is a pic
Is there a way so that only the bottom nav controller is visible?
If I understand your question correctly, you want to hide the ui for the enclosing navigation controller - i.e. the nav bar. You can do that by setting it hidden in the viewDidLoad() function of that view controller:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
}

UINaviagtionBar subview doesn't fade out during UIViewController "Back" transition

I have a UINavigationBar based app. I've created a custom UIView with some titles and added it as a subview to the navigation bar:
[self.navigationController.navigationBar addSubview:_navbarView];
Everything works ok until I hit the back button in the navigation bar and the UIViewController transition occurs.
The problem is that my custom view doesn't fade away like the others elements in the UINavigationBar, it just stays the same and disappears when the transition is complete.
I want it to fade away during the transition like the native elements of the UINavigationBar, is there any way to achieve this?
If you add a subview to the navigation bar, then it will just stay there; the navigation controller doesn't know to do anything special with it. You say your custom view has "some titles" - have you tried doing this instead?
self.navigationItem.titleView = _navbarView;
Then the navigation controller knows that the view should be used in place of your controller's title, and it should animate in and out.
If that doesn't work, you'll need to look at becoming the navigation controller's delegate. Since iOS7, this can get quite complex.
If you need custom navigation bar it could be a good idea to create UINavigationController with custom UINavigationBar
- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass
in your navigation bar class you can implement
- (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated
{
if (animated) {
//your_problem_view animation here
}
[super popNavigationItemAnimated];
}

Resources