PresentModalViewController not showing navigation bar on next view - iphone

Hello I am using One tab bar button on toolbar , this button will show next view with table view ,Here is my code
[self presentModalViewController:self.navigationController
animated:YES];
my problem is that when I click this tab bar button it will showing next view with tableview but not navigation bar. because of this i am unable to perform delete operation in tableView.
How to solve the issue?

If you dont find the UINavigationBar on the next class means , it does not have a navigation controller, so before pushing it add a UINavigationController to your next view.
Try like this:
NextViewController *nextViewController=[[NextViewController alloc]initWithNibName:#"NextViewController" bundle:nil];
UINavigationController *navBar=[[UINavigationController alloc]initWithRootViewController:nextViewController];
[self.navigationController presentModalViewController:navBar animated:YES];
[navBar release];
[nextViewController release];
see this stackoverflow question for edit option.
You can simply add a button to navigation bar with ease
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(editTable)] autorelease];
-(void)editTable{
[tableView setEditing: YES animated: YES];
}
All the best.

This code is called on button click event in classA VC:
ClassBVC* bVc = [[ClassBVC alloc] initWithNibName:#"ClassBVC" bundle:nil];
UINavigationController* tempNavCon = [[UINavigationController alloc] initWithRootViewController:bVc];
[self presentModalViewController:tempNavCon animated:YES];
[tempNavCon release];
[bVc release];
bVc = nil
;
and in class BVC in view did load you make an UIbarbutton item e.g:
UIBarButtonItem* barButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(backButtonClicked:)];
[barButton setTitle:#"Back"];
[self.navigationItem setLeftBarButtonItem:barButton];
[barButton release];
And in buttonClickedMethod simply dismiss the the model controller as:
-(void)backButtonClicked:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}

That is because you are using Modal to bring the new view controller.
Modally added/presented view controller will not be added to the navigation controller stack

if you are using navigationcontroller use like this
[self.navigationController pushViewController:nextController animated:YES];

Add navigation bar as sub view to the new view with bar button.
Try this
-(IBAction) editClick:(id)sender
{
[tableView setEditing:![tableView isEditing] animated:YES];
}

Swift 5
import UIKit
class ListVC: UIViewController {
// MARK: - Init
override func viewDidLoad() {
super.viewDidLoad()
//Background of the first screen
view.backgroundColor = .yellow
//Calling the instance of the navigation controller
let nav = self.navigationController?.navigationBar
//Defining the black theme on the navigation controller
nav?.barStyle = UIBarStyle.black
//Defining the white characters to make contrast with the black theme on the navigation controller
nav?.tintColor = UIColor.white
//Defining the custom color of the title font from navigation controller
nav?.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.orange]
//Defining the title of the navigation controller
nav?.topItem?.title = "List"
navigationItem.rightBarButtonItem = UIBarButtonItem.init(image: #imageLiteral(resourceName: "AddBtn"), style: .plain, target: self, action: #selector(hello))
// print(Realm.Configuration.defaultConfiguration.fileURL)
let realm = try! Realm()
print(Realm.Configuration.defaultConfiguration.fileURL)
}
// MARK: - Selector
/// A selector function that is called when the 'add' button is pressed on the navigation controller
#objc func hello() {
//Instance of the second screen
let addVC = AddVC()
//Add the navigationController to the new viewController
let navController = UINavigationController(rootViewController: addVC)
//Presenting the second screen modally
navigationController?.present(navController, animated: true, completion: nil)
}
}
//Other class
import UIKit
class AddVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Background of the view
view.backgroundColor = .white
//Calling the instance of the navigation controller
let nav = self.navigationController?.navigationBar
//Initialize the title for the ViewController
nav?.topItem?.title = "Andrey"
// Initialize the right bar button item
navigationItem.rightBarButtonItem = setUpSaveButton()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
/// Function that returns the "Save" bar button item
private func setUpSaveButton() -> UIBarButtonItem {
let button = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(saveAction))
button.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.systemBlue],
for: .normal)
return button
}
#objc func saveAction() {
print("Saving..")
}
}

Swift 5.1
Presenting ViewController with navigation bar AND toolbar in fullscreen mode. If you don't put the row marked on comment the toolbar never show itself.
let sb = UIStoryboard(name: "retail_mainScreen", bundle: nil)
guard let mainVC = sb.instantiateViewController(withIdentifier: "mainScreen") as? retail_mainGest else { return }
let navController = UINavigationController(rootViewController: mainVC)
navController.isToolbarHidden = false //<--- remember this or toolbar will not appear
navController.modalPresentationStyle = .fullScreen
sender.vista.present(navController, animated: true, completion: nil)

Related

TabBar controls the NavigationBar

I added 2 ViewControllers into a TabBar, but now, the TabBar's NavigationBar 'took over' each view's NavigationBar.
I can't set a title for each one of them, I can't add buttons, nothing.
I tried a few solutions to solve it that I found on the internet, but nothing worked.
I need control over the NavigationBar of each one of the views, as I need them to be different, with different title, etc.
This is my TabBar code:
class TabBar: UITabBarController {
let homeVC = HomeVC()
let followingVC = FollowingVC()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.appColors.mainWhite]
navigationController?.navigationBar.tintColor = UIColor.appColors.mainWhite
navigationItem.setHidesBackButton(true, animated: false)
homeVC.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 0)
followingVC.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 1)
let tabBarList = [homeVC, followingVC]
viewControllers = tabBarList
}
}
I really need the option to configure each NavigationBar from it's own ViewController, or atleast from the TabBar class.
You should add UINavigationController to each of your ViewControllers not your UITabBarController
First remove the UINavigationController of your TabBar, Either you have done this pragmatically or in the storyboard remove that first.
Second add UINavigationController to you ViewControllers
class TabBar: UITabBarController {
let homeVC = HomeVC()
let followingVC = FollowingVC()
override func viewDidLoad() {
super.viewDidLoad()
homeVC.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 0)
followingVC.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 1)
let homeNavigationController = UINavigationController(rootViewController: homeVC)
let followingNavigationController = UINavigationController(rootViewController: followingVC)
let tabBarList = [homeNavigationController, followingNavigationController]
viewControllers = tabBarList
}
}
Now if you change any properties like title and barButtons it will reflect accordingly.
Figured it out, the solution is:
The NavigationBar was not the TabBar navigation bar, but the screen that lead to the TabBar (Login Screen for example), I fixed it by hidding the navigation bar of the login screen when transfering to the TabBar controller, now the navigation bar of each view controller is shown and not blocked by the Login Viewcontrolelr navigationbar.

Swift - Expand ViewController behind the TabBar

I created three tabItems in UITabBarViewController which is pushed to another UINavigationController. One of the three tabItems is a UINavigationController, the other two are UIViewController. In order to make sure there is only one navigation bar is shown when it is in non-root viewController of the tabItem which is a UINavigationController, the parent UINavigationBar will be hidden.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationC = self.navigationController, navigationC.viewControllers.count == 1 {
self.navigationController?.setNavigationBarHidden(true, animated: false)
self.parent?.navigationController?.setNavigationBarHidden(false, animated: false)
} else {
self.navigationController?.setNavigationBarHidden(false, animated: false)
self.parent?.navigationController?.setNavigationBarHidden(true, animated: false)
}
self.setupViewConstraints()
}
The issue here is, if I navigate to the 2nd UIViewController of the UINavigationController, then switch from UINavigationController to UIViewController and back to the UINavigationController, the bottom of the UINavigationController is moved up which should equal to the bottom of the UIScreen. If I navigate back to the root view of the UINavigationController, the bottom of the UINavigationcontroller is equal to the UIScreen which is correct.
How can I make sure all UIViewControllers' bottom in the navigationController is equal to UIScreen? It may due to there are two navigationBar in the non-root viewController of UINavigationController tabItem.
Below is the code I used to create UITabBarViewController:
override func viewDidLoad() {
super.viewDidLoad()
tabBar.tintColor = UIColor.fromHexString("0078d7")
tabBar.barTintColor = UIColor.white
let firstViewController = FirstViewController()
firstViewController.delegate = self
firstViewController.tabBarItem = UITabBarItem.init(title: "first", image: , tag: 0)
let secondViewController = SecondViewController()
secondViewController.delegate = self
secondViewController.tabBarItem = UITabBarItem.init(title: "second", image: , tag: 1)
let thirdViewController = ThirdViewController()
thirdViewController.delegate = self
thirdViewController.tabBarItem = UITabBarItem.init(title: "third", image: , tag: 3)
let initialNavigationController = UINavigationController(rootViewController: firstViewController)
initialNavigationController.navigationItem.title = ""
self.addChildViewController(initialNavigationController)
self.addChildViewController(secondViewController)
self.addChildViewController(thirdViewController)
self.navigateToLastVisitedViewController(navigationController: initialNavigationController)
}
In above viewDidLoad method of UITabBarViewController just make your tabBar translucent. This will allow you content viewController to lay beneath UITabBar object.
Swift
self.tabBar.isTranslucent = true
Objective-C
[self.tabBar setTranslucent:YES];
Same logic will be use in UINavigationBar case.

How to remove custom nav bar back button

I am adding some subview to main view controller. When I add one of these subview, I create a custom back button so that it will go back to main view controller, not the prior view controller in the navigation stack. I can add it programmatically but I can't seem to figure out how to delete it. Any help is greatly appreciated!
func createCustomBackButton() {
self.navigationItem.hidesBackButton = true
let customFont = UIFont.systemFontOfSize(26.0)
UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName: customFont], forState: UIControlState.Normal)
// customBackButton is a property I set for UIBarButtonItem
customBackButton = UIBarButtonItem(title: "<", style: .Plain, target: self, action: "back:")
self.navigationItem.leftBarButtonItem = customBackButton
}
func back(sender: UIBarButtonItem) {
UIView.animateWithDuration(0.3, animations: {
self.containerView.alpha = 0
}, completion: { finished in
self.view.sendSubviewToBack(self.containerView)
self.navigationItem.hidesBackButton = false
// what do I do on this line to get this to disappear or set to nil??
self.customBackButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.z, target: self, action: nil)
// clears out prior view that was there to free up memory
for view in self.containerView.subviews {
view.removeFromSuperview()
}
})
}
Using self.navigationItem.leftBarButtonItem = nil will reset the leftBarButtonItem back to the default.
You should use an unwind segue. If you're using storyboards, drag from the "destination viewcontroller" to the thing that looks like a sideways share button (exit button) of the VC you want unwind from. Name it whatever you'd like, we'll call it "unwind"
and then call in the same VC:
self.performSegueWithIdentifier("unwind", sender: self)
in the VC you want to unwind back to:
#IBAction func unwindToMapSegue(segue: UIStoryboardSegue) {
// do something
}

hide tab bar in view with push

I have a tabBar + NavigationViewController. The Tab bar has collection view with cells(Say view1) and with cells a push seague is implemented to another view(Say view2).
In view2 I want to have a navBar but no tab bar.
I tried
self.tabBarController?.tabBar.hidden = true,
it worked fine for view2 but when I went back to view1 by back button the tab was still hidden( even after in view1 class I added self.tabBarController?.tabBar.hidden = false in viewDidLoad func).
How can i make the tab bar reappear in view1?
I'm working in swift.
Make sure to check this option only on the ViewController whose tab
bar you wish to be hidden.
Thanks to iHarshil for the suggestion.
In the viewDidload set the UIViewController hidesBottomBarWhenPushed to yes:
self.hidesBottomBarWhenPushed = YES;
This way the UINavigationController takes care of hiding the tab bar.
Use in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.recipeName = [recipes objectAtIndex:indexPath.row];
// Hide bottom tab bar in the detail view
destViewController.hidesBottomBarWhenPushed = YES;
}
}
Bruno Fernandes's answer in Swift:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "YourSegueIdentifier" {
let destinationController = segue.destinationViewController as! YourViewController
destinationController.hidesBottomBarWhenPushed = true
}
}
This was the answer that worked for me. Putting hidesBottomBarWhenPushed in the viewDidLoad method didn't work.
Thanks Bruno!
In my case, I use hidesBottomBarWhenPushed before I push the destination view controller.
func showSecondViewController() {
let vc = SecondViewController()
vc.hidesBottomBarWhenPushed = true
self.navigationController?.pushViewController(vc, animated: true)
}
You have to work with viewWillAppear or viewDidAppear. viewDidLoad will be called when view1 is loading (showing) the first time. If you move from view1 to view2 and back the viewDidLoad won't be called again. Therefore you have to use viewWillAppear or viewDidAppear like
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.hidden = false
}
Put this code in your view1 controller. The viewWillAppear or viewDidAppear will be called every time navigating back to view1
if you want to hide TabBarController Bottom Bar : #Swift 3
In YourViewController : in ViewDidLoad() method
self.tabBarController?.tabBar.isHidden = false

Adding a NavigationBar to UITableViewController programmatically?

I am trying to create a uitableviewcontroller as a modal viewcontroller to edit some settings. I am creating the tableviewcontroller in code and the thing i am struggling with currently is how to correctly add a navigation bar to the controller which will have a "Done" button on it that:
a) doesnt appear on top of the tableview and
b) does not scroll with the tableview??
This happens when i add the navbar to the contoller with:
[self.view addSubview:navigationBar];
This adds a navbar to the controller which goes on top and obscures the tables first row and also scrolls with the view?
I also thought about simply using a uiviewcontroller with a separate tableview however i like the funcitonality of automatically scrolling the tableview when editing a textfield that the tableviewcontroller gives you. Just cant figure how to setup this navbar??
thx
Just create UINavigationcontroller as the modal viewcontroller, and add the tableview as its root view controller.
Use Navigation controller as modalviewController(as suggested in the other answer). Here is the code:
UINavigationController *Controller = [[UINavigationController alloc] init];
//LoginViewController is a sub class of UITableviewController
LoginViewController *controller = [[LoginViewController alloc] init];
Controller.viewControllers=[NSArray arrayWithObject:controller];
[self presentModalViewController:Controller animated:YES];
[controller release];
[Controller release];
In Swift:
AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
/*
#1. Instantiate a navigation controller and add the table view controller
as a child view controller.
*/
let navigationController = UINavigationController()
// Instantiate your desired ViewController
let storyboard = UIStoryboard(name: UIStoryboardName.Main.rawValue, bundle: nil)
let tableViewController = storyboard.instantiateViewControllerWithIdentifier("TableViewControllerID")
navigationController.addChildViewController(tableViewController)
/*
#2. Then we set the title of the navigation bar and add two bar button items.
*/
// We set the title of the navigation bar.
tableViewController.navigationItem.title = "My Title"
// Create left and right button for navigation item.
let leftButton = UIBarButtonItem(title: "Save", style: UIBarButtonItemStyle.Plain, target: tableViewController, action: "saveButtonClicked:")
let rightButton = UIBarButtonItem(title: "Right", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
// Create two buttons for the navigation item.
tableViewController.navigationItem.leftBarButtonItem = leftButton
tableViewController.navigationItem.rightBarButtonItem = rightButton
/*
#3. To finish we set the root view controller with the navigation controller.
*/
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
TableViewController.swift
// Method called when the user clicks on the Save bar button item.
func saveButtonClicked(sender: UIBarButtonItem) {
// Do something.
print("Save bar button item has been clicked!!!")
}