Swift Navigation Bar Button and Title don't appear - swift

I'd like to create a Navigation bar on top of my App. I created an Navigation Controller -> Tab Bar Controller -> Navigation Controller -> Table Controller
I dragged a Bar Button Item on the upper right side.
I double clicked the title in the middle of the Table Controller and wrote a text.
I also tried it with this code in the viewDidLoad() of my controller:
self.navigationController.navigationBar.topItem.title = "some title"
self.navigationItem.setRightBarButtonItem(UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: "barButtonItemClicked:"), animated: true)
self.navigationItem.title = "YourTitle"
Non of it worked - what am I doing wrong? :/

You can try something like this:
self.title = "Your Title"
var homeButton : UIBarButtonItem = UIBarButtonItem(title: "LeftButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: "")
var logButton : UIBarButtonItem = UIBarButtonItem(title: "RigthButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: "")
self.navigationItem.leftBarButtonItem = homeButton
self.navigationItem.rightBarButtonItem = logButton

I believe you are looking for a titleView.
Try:
var navBarTitleView = UIView(frame: CGRectMake(0.0, 0.0, self.view.frame.width, 44.0))
navBarTitleView.backgroundColor = UIColor.brownColor()
self.navigationItem.titleView = navBarTitleView

I am pretty sure that you can just set the title of your table controller, in its viewDidLoad, which is the title displayed in your navigation bar.
this answer explains a slightly different question, but the concept is the same:
https://stackoverflow.com/a/25167491/2070902

if you want to set your "UINavigationBar" according to your wish Please follow this very safely ,its so simple in swift language ,hope it will help you a lot .
STEP 1:-
Create a category class in swift just go on "New file" and add "Simple swift class " and given it name "MyCustomNavBarCategory.swift"
STEP 2:-
Just "Clean the class (remove all code from this class)" and "Paste my give code below" :-
//class will Start from below line start copy from here
let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height
import UIKit
extension UINavigationBar {
//First increase navigation bar height .
override public func sizeThatFits(size: CGSize) -> CGSize {
NSLog("%f", SCREEN_HEIGHT*0.06);
let newSize:CGSize = CGSizeMake(self.frame.size.width, SCREEN_HEIGHT*0.10)
return newSize;
}
//then set layOut of your Custom Nav for several objects like titleview,buttons and all
public override func layoutSubviews() {
for var view in self.subviews
{
NSLog("view %#", view);
let str :String = view.classForCoder.description();
if(str == "UILabel")
{
//play with title view frame
var f = view.frame;
f.origin.y = self.frame.size.height/2 - view.bounds.size.height/2 ;
view.frame = f;
view.backgroundColor = UIColor.greenColor();
}
else if(str == "UIButton")
{
//play with buttons of navigation bar view frame
var f = view.frame;
f.origin.y = (self.frame.size.height/2) - (view.bounds.size.height/2) ;
view.frame = f;
view.backgroundColor = UIColor.greenColor();
}
}
}
}
//class will end on above stop copy code on above line and just past this in to your "MyCustomNavBarCategory.swift". that's it enjoy ;).
STEP 3:-
Now you can set any frame to any object of UINavigationBar in this class "It's very powerful category of UINavigationBar if you will implement it carefuly".

Related

How to Change back button title on navigation controller in swift3?

I want to change the title of backbutton to any name in swift 3.I tried many ways but none of them worked for me.
self.navigationItem.backBarButtonItem?.title="Title"
self.navigationController?.navigationItem.backBarButtonItem?.title="Title"
Just for information i have written below code in appdelegate.
let backImage : UIImage = UIImage(named:"backArrow")!
UINavigationBar.appearance().barTintColor = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0)
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white]
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, 0), for: .default)
IQKeyboardManager.sharedManager().enable = true
self.window?.backgroundColor = UIColor.white
Navigation item back button name will be same as the title of previous view controller which is pushing it to the navigation stack :)
So if VC A pushes VC B, back button in VC B will be A.
So all you can do is, to change the title of the previous viewController before pushing the new viewController using code :)
self.navigationItem.title = "ABCD"
And in ViewWillAppear of VC A,you can revert the title back to whatever it was earlier :)
self.navigationItem.title = "Back to xyz"
All that being said, if you don't want all this circus :) you can simply hide the default back button using,
self.navigationItem.hidesBackButton = true
in your VC B, create a UIBarButton item, set whatever the title you want to set and then set that as leftBarButtonItem :) using,
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("ABCD", comment: "ABCD"), style: .plain, target: self, action:#selector(self.abcdTapped:)
of course now that will not show "<" icon :) Now if you want that as well you can add it as a image to back bar button item :) but its cumbersome :)
Hope it helps :)
You will have to set the backBarButtonItem property of the navigationItem of the viewController that you push the said viewController from.
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
However, you must set this for each viewController.
This is the way:
extension UINavigationController {
func addCustomBackButton(title: String = "Back") {
let backButton = UIBarButtonItem()
backButton.title = title
navigationBar.topItem?.backBarButtonItem = backButton
}
}
In Swift 3.0 put below code in appdelegate didFinishLaunchingWithOptions method its worked perfectly for me
let backImage = UIImage(named: "BackNavigation")?.withRenderingMode(.alwaysOriginal)
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -80.0), for: .default)
The last line will remove the title of Navigation Back Button if you don't want to remove title then just comment it
I didn't find the answer that I was looking for so I share with you my solution.
Sometimes you have to change the text of the back button in the parent ViewController and not in the ViewController where seems to be defined the back button, remember that a navigation controller stacks ViewControllers one after another.
In my case I did this on the function prepare(for segue: ) of the "ParentViewController":
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showChildViewController" {
if let childViewController = segue.destination as? ChildViewController {
let backItem = UIBarButtonItem()
backItem.title = "Back"
navigationItem.backBarButtonItem = backItem
}
}
Try following steps to set image to your back button..
Output:
Step 1:
Add following code to your AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
var backButtonImage = UIImage(named: "Your Image Name")
backButtonImage = backButtonImage?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 0)
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)
UINavigationBar.appearance().barTintColor = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0)
UINavigationBar.appearance().tintColor = UIColor.white
return true
}
Step 2:
Add following code to your MainVC
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
title = "Title 1"
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white, NSFontAttributeName:UIFont(name:"HelveticaNeue", size: 20)!]
}
Step 3:
Add following code to your DestVC or 2ndVC
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
title = "Title 2"
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white, NSFontAttributeName:UIFont(name:"HelveticaNeue", size: 20)!]
}
Step 4:
Select your navigationBar from your StoryBoard and goto Attribute Inspector. Under Navigation Item change your Back Button name enter a empty space or programatically create a back button with plain title..
Step 5:
Add icon image to your Assets. 1x29pt,2x58pt and 3x87pt. I am not sure about the asset image size.Check with apple doc about the size class..
Update:
My Similar answer related to this post.
How to customize the navigation back symbol and navigation back text?
You can easily do that from the storyboard by setting the title of the previous screen. Image explaining how to do that from storyboard - or you can do that by adding the following code to the view controller you're navigating BACK to.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
let backItem = UIBarButtonItem()
backItem.title = "Title"
navigationItem.backBarButtonItem = backItem
}
in viewDidLoad()
let backBarButtonItem = UIBarButtonItem(title: "You back button title here", style: .plain, target: nil, action: nil)
navigationItem.backBarButtonItem = backBarButtonItem

Why LeftBarButtonItem doesn't appear in the navigationbar in swift

I have two view A and view B.
From view A to view B, I do not use navigation controller, I used performSegueWithIdentifier() and I don't want to use navigation controller to pass view A to view B.
But in the view B, I want to add a leftBarButtonItem in the navigation bar(I have embed a navigation controller for view B) like a back button with a arrow.
In order to achieve 100% same with the system backbitten with arrow. I use NSMutableAttributedString and UIButton. code is below:
let string = "< Retour" as NSString
var attributedString = NSMutableAttributedString(string: string as String)
let ArrowAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont.systemFontOfSize(20)]
let TextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont.systemFontOfSize(10)]
attributedString.addAttributes(ArrowAttributes, range: string.rangeOfString("<"))
attributedString.addAttributes(ArrowAttributes, range: string.rangeOfString(" Retour"))
let backbutton = UIButton(type: .Custom)
backbutton.addTarget(self, action: "back:", forControlEvents: .TouchUpInside)
backbutton.setAttributedTitle(attributedString, forState: UIControlState.Normal)
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: backbutton), animated: true)
rightBtn = UIBarButtonItem(title: "Ok", style: .Plain, target: self, action: "save:")
But I can not see left button in the navigation bar in view B…why I can not see it in the navigation bar? Why the left button disappear?
Thank you very much.
I have tried the new code for a label, but it doesn't work yet...
let barButtonBackStr = "< Back"
let attributedBarButtonBackStr = NSMutableAttributedString(string: barButtonBackStr as String)
attributedBarButtonBackStr.addAttribute(NSFontAttributeName,
value: UIFont(
name: "AmericanTypewriter-Bold",
size: 18.0)!,
range: NSRange(
location:0,
length:1))
let label = UILabel()
label.attributedText = attributedBarButtonBackStr
label.sizeToFit()
let newBackButton = UIBarButtonItem(customView: label)
self.navigationController!.navigationItem.setLeftBarButtonItem(newBackButton, animated: true)
Thank you
Try a backbutton.sizeToFit() you'll see your button
You create a button but you never set the frame
You can also set the frame directly instead of sizeToFit() method like backbutton.frame = CGRectMake(0, 0, 100, 20)
PS: TextAttributes wasn't used
You must write it to :
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
...
}
Try to set a breakpoint after your UI design and try to launch the Debug View Hierarchy to see if your button exist or is hidden by another object
Next, after you have set your button try to make:
self.navigationController!.navigationItem.leftBarButtonItem.customView.sizeToFit()

Set textfield in UISearchBar

I'm trying to add SearchController to UINavigationBar. I'm trying to set UITextField of UISearchBar after back button of UINavigationController. I want some more space after back button
When I start searching it appears as
Whereas I should be able to view back button. Only textfield width should be decreased. Also after Cancel it should be again back to initial layout. Whereas it is displayed as below:
Below is my code
var searchResultController = UISearchController()
self.searchResultController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.searchBar.delegate = self
controller.hidesNavigationBarDuringPresentation = false
self.navigationController?.navigationBar.addSubview(controller.searchBar)
return controller
})()
override func viewDidAppear(animated: Bool) {
for subView in searchResultController.searchBar.subviews{
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
var bounds: CGRect
bounds = textField.frame
bounds.size.width = self.view.bounds.width - 50
}
}
}
}
Please let me know how can I fix this.
Thanks in advance
For setting the UIsearchBar add it to Navigation's titleView as
self.navigationItem.titleView = controller.searchBar
For removing Cancel button we can use UISearchControllerDelegate method
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
Hope this may help any one.

Non Standart UITabBarItem Action

I have UITabBarController with view
So on every TabBar I have ViewController. But on my center UITabBarItem I need to call something like modal UIViewController. And It should be like this
My UITabBarController class look like
class PlanetTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.tintColor = kTintColor
var items = self.tabBar.items as! [UITabBarItem]
let centredTabBar:UITabBarItem = items[2]
self.tabBar.layer.borderWidth = 0.50
centredTabBar.image = ktabCentredBarImage
self.tabBar.layer.borderColor = UIColor.clearColor().CGColor
self.tabBar.layer.borderWidth = 0
self.tabBar.shadowImage = UIImage()
// self.tabBar.backgroundImage = ktabBarImage
self.tabBar.backgroundImage?.imageWithAlignmentRectInsets
print( UIDevice.currentDevice().modelName)
if( UIDevice.currentDevice().modelName != "iPhone 6" && UIDevice.currentDevice().modelName != "iPhone 6 Plus") {
self.tabBar.backgroundImage = ktabBarImage
}
if( UIDevice.currentDevice().modelName == "iPad 2" ) {
self.tabBar.backgroundImage = ktabBarImage
}
if let font = UIFont(name: "Avenir-Black", size: 10) {
let appearance = UITabBarItem.appearance()
let attributes = [NSFontAttributeName:font]
appearance.setTitleTextAttributes(attributes, forState: UIControlState.Normal)
}
}
}
I really have no idea how to override standart calling of UIViewController and call modal like this =) Please give me advice where I need to search
You can either place a UIButton in the same area as the UITabBarItem and fire an action or you can simply fire an action when the selectedSegmentIndex changes("value changed" in IB) for the UITabBar after creating a center UITabBarItem. The design choice is yours. The first step is to understand the objects you're working with. It would probably be easier to just add a button, center aligned, over top of the standard UITabBar at the bottom so you don't deal with a custom UITabBarController to handle that non-uniform image above the tab bar.
Or just create your own TabBar down there. It's very simply to setup a few UIButtons or UIViews next to one another that don't have a static height such as a UITabBarController which would allow for that center object.
UITabBarController
UIViewController
Presenting a ViewController

Changing navigation title programmatically

I have a navigation bar with a title.
When I double click the text to rename it, it actually says it's a navigation item, so it might be that.
I'm trying to change the text using code, like:
declare navigation bar as navagationbar here
button stuff {
navigationbar.text = "title"
}
That's not my code obviously, just showing how it would work.
So whenever I press the button, I want the title to change.
You change the title by changing the title of the view controller being displayed:
viewController.title = "some title"
Normally this is done in view did load on the view controller:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "some title"
}
However, this only works if you have your view controller embedded in a UINavigationController. I highly recommend doing this instead of creating a navigation bar yourself. If you insist on creating a navigation bar yourself, you can change the title by doing:
navigationBar.topItem.title = "some title"
Try the following in viewDidLoad
self.navigationItem.title = "Your Title"
The code below works for me with Xcode 7:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Your Title"
}
I found this to work:
navigationItem.title = "Title"
Swift 5.1
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "What ever you want"
}
and also if you will try to create Navigation Bar manually this code will help you
func setNavBarToTheView() {
let navBar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 64.0))
self.view.addSubview(navBar);
let navItem = UINavigationItem(title: "Camera");
let doneItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.cancel, target: self, action: #selector(CameraViewController.onClickBack));
navItem.leftBarButtonItem = doneItem;
navBar.setItems([navItem], animated: true);
}
The correct answer for people using swift4 would be
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Your Text"
}
Normally, the best-practice is to set the title on the UIViewController. By doing this, the UINavigationItem is also set. Generally, this is better than programmatically allocating and initializing a UINavigationBar that's not linked to anything.
You miss out on some of the benefits and functionality that the UINavigationBar was designed for. Here is a link to the documentation that may help you. It discusses the different properties you can set on the actual bar and on a UINavigationItem.
Just keep in mind:
You lose back button functionality (unless you wire it yourself)
The built-in "drag from the left-hand side to swipe back" gesture is forfeited
UINavigationController's are your friends.
If you have a NavigationController embedded inside of a TabBarController see below:
super.tabBarController?.title = "foobar"
You can debug issues like this with debugger scripts. Try Chisel's pvc command to print every visible / hidden view on the hierarchy.
Swift 3
I created an outlet for the navigation title bar item that comes with the navigation bar (from the Object Browser) in the storyboard. Then I sued the line below:
navigationBarTitleItem.title = "Hello Bar"
If you wanted to change the title from a child view controller of a Page View Controller that's embedded in a navigation controller, it would look like this:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.parent?.title = "some title"
}
If you have not created navigation bar in your view controller from storyboard this will work.
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Title"
}
If you have created navigation bar in your view controller from storyboard this will be helpful.
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Title"
}
in viewDidLoad
navigationController?.navigationBar.topItem?.title = "Your Text"
This worked for me. Just connect an outlet to your nav bar and access the title through the topItem
navBar.topItem?.title = "Your Title Here"
In Swift 4:
Swift 4
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Your title"
}
I hope it helps, regards!
I prefer using self.navigationItem.title = "Your Title Here" over self.title = "Your Title Here" to provide title in the navigation bar since tab bar also uses self.title to alter its title. You should try the following code once.
Note: calling the super view lifecycle is necessary before you do any stuffs.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupNavBar()
}
}
private func setupNavBar() {
self.navigationItem.title = "Your Title Here"
}
Swift 5.1
// Set NavigationBar Title Programmatically and Dynamic
Note :
First add NavigationControllerItem to Your ViewController then goto their ViewController.swift file and Just Copy and Paste this in viewDidLoad().
navigationItem.title = "Your Title Here"
e.g.
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Your Title Here"
}