I am developing an app that contains a login and when logging in for the first time the views that go after logging do not load well the navigation bar, when opening the app for the second time and already with the credentials previously entered, this time if they load well the navigation bar.
Does anyone know why this happens?
my viewWillAppear is like this
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 38, height: 38))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "img_header")
imageView.image = image
navigationItem.titleView = imageView
//let image_home = UIImage(named: "ic_home")
//let homeButton = UIBarButtonItem(image: image_home, style: UIBarButtonItemStyle.done, target: self, action: #selector(self.cancelMetod2))
// navigationItem.leftBarButtonItem = homeButton
let color_primary: UIColor = val_colores.hexStringToUIColor(val_colores.colorPrimary)
let color_background_primary: UIColor = val_colores.hexStringToUIColor(val_colores.ColorGrisClaro2)
//icono more
let imagen_more = UIImage (named: "ic_more_menu")!
let buttonMore: UIBarButtonItem = UIBarButtonItem(image: imagen_more, style: UIBarButtonItemStyle.done,target: self, action: #selector(self.moreMetod))
self.navigationItem.rightBarButtonItem = buttonMore
//background color
self.navigationController?.navigationBar.barTintColor = color_primary
//back button color
UIBarButtonItem.appearance().tintColor = color_background_primary
//Since iOS 7.0 UITextAttributeTextColor was replaced by NSForegroundColorAttributeName
//title color
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: color_background_primary]
//color in carrier, hour, battery
UINavigationBar.appearance().barStyle = UIBarStyle.black
self.navigationController!.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: color_background_primary]
self.navigationController!.navigationBar.barStyle = UIBarStyle.black
self.navigationController!.navigationBar.tintColor = color_background_primary
}
Related
I have an app with a left (hamburger) navigationItem.leftBarButtonItem and we've set the titleView to the logo of the company. The problem is that they want the logo next to the hamburger. The hamburger button is set in the Storyboard's ViewController and the logo is programmatically, like this:
let logo = UIImage(named: "logo.png")
let imageView = UIImageView(image:logo)
imageView.frame = CGRect(x: 0, y: 0, width: 120, height: 60)
navigationItem.titleView = imageView
Is there a way to move it to the left?
UPDATE:
Regarding the suggestions to use leftBarButtonItems
I've done this in another UIViewController and the result wasn't as I expected it to be.
Here's the code:
let logo = UIImage(named: "logo")!
let karambaButton = UIBarButtonItem(image: logo, style: .plain, target: self, action: nil)
let backBTN = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: navigationController, action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItems = [backBTN, logoButton]
And here's the result of it:
(The dark block is the image, I had to cover it up because it's a client)
You can set multiple left bar button items by acessing:
navigationItem.leftBarButtonItems = [barItem1, barItem2]
Same with the right side. :)
You can also set auto layout programmatically.
imageView.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = imageView.leadingAnchor.constraint(equalTo: hamburgerButton.trailingAnchor, constant: 10)
let verticalConstraint = newView.centerYAnchor.constraint(equalTo: hamburgerButton.centerYAnchor)
let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 120)
let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 120)
imageView.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
UINavigationItem has a property named leftBarButtonItems.
Put your logo imageView into the customView property of a UIBarItem and size it correctly and you should be all set. Just add it to the the array along with the hamburger button.
edited to add -- try using a custom view, that is:
if let logo = UIImage(named: "logo") {
let imageView = UIImageView(image:logo)
let karambaButton = UIBarButtonItem(customView: imageView)
let backBTN = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: navigationController,
action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItems = [backBTN, logoButton]
}
I know there are a lot of questions out there on this topic; however, none of those answers have helped me and I have tried so many ways of going about solving this. My problem is that my bar button will not show up, originaly, but when the viewcontroller is presented later on in the app it will show up then but the navigation title won't show up. I'm not sure why that is, but I believe it has something to do with the SwipeNavigationController framework that I'm using. My goal is to have the button show up as it's supposed to when the user swipes left to get to that view, and also when the view is later called and presented to look the same. The code for adding the navItem is below:
let cameraBarButton = UIBarButtonItem(image: #imageLiteral(resourceName: "cameraIcon"), style: .plain, target: self, action: #selector(goToCamera))
navigationItem.rightBarButtonItem = cameraBarButton
Please look at this other post to get a little better understanding of the framework. As well as here is the code on how I set up the navigation bar:
override func viewDidLoad() {
super.viewDidLoad()
setupView()
let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = self.view.frame.height
messagesTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
messagesTableView.register(BlankCell.self, forCellReuseIdentifier: blankCellID)
messagesTableView.dataSource = self
messagesTableView.delegate = self
self.view.addSubview(messagesTableView)
view.backgroundColor = UIColor.white
setupNavButtons()
setupNavBar()
showNoMessagesLabel()
navigationController?.isNavigationBarHidden = false
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
} else {
// Fallback on earlier versions
}
}
override func viewWillAppear(_ animated: Bool) {
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
setupNavBar()
} else {
setupNavBar()
}
}
func setupNavBar() {
UIApplication.shared.statusBarStyle = .lightContent
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.topItem?.title = "Messages"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
self.navigationController?.navigationBar.barTintColor = UIColor.pinkNeonColor
self.navigationController?.navigationBar.tintColor = UIColor.white
}
func setupNavButtons() {
let cameraButton = UIButton(type: .system)
cameraButton.setImage(#imageLiteral(resourceName: "cameraIcon").withRenderingMode(.alwaysOriginal), for: .normal)
cameraButton.frame = CGRect(x: 0, y: 0, width: 34, height: 34)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: cameraButton)
}
I have got this code in my AppDelegate
UINavigationBar.appearance().backIndicatorImage = #imageLiteral(resourceName: "backarrow")
And this code shows something like this
How can i resize and change the position of the image?
Hi you can implement it the following way: -
var backImage = UIImage(named: "backarrow")
backImage = resizeImage(image: backImage!, newWidth: 40) //the width that you want for the back button image
UINavigationBar.appearance().backIndicatorImage = backImage
And here is the image resize function
func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? {
let scale = newWidth / image.size.width
let newHeight = image.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
You have to change the button by a custom one.
Define a UIBarButtonItem and replace the default one by your custom button.
var customButton = UIBarButtonItem(image: closeButtonImage, style: .plain, target: self, action: #selector(YourController.backPressed(_:)))
self.navigationItem. backBarButtonItem = customButton
Just use a custom UIBarButtonItem and hide the default one.
let backButton = UIBarButtonItem(image: UIImage(named: "Your_Back_Button_Image", style: .plain, target: self, action: #selector(popCurrentViewController)
self.navigationItem.setHidesBackButton(true, animated: true)
self.navigationItem.leftBarButtonItem = backButton
To implement back functionality:
func popCurrentViewController(_ animated: Bool)
{
_ = self.navigationController?.popViewController(animated: true)
}
I am trying to use Swift's internal back button image.
I have asked this question before and got the technically correct answer that it inherits it from the previous View, BUT if I insert this code you can control the back button on the current View.
// Takeover Back Button
self.navigationItem.hidesBackButton = false
let newBackButton = UIBarButtonItem(title: "<", style: .Plain, target: self, action: "segueBack")
navigationItem.leftBarButtonItem = newBackButton
That gives me a <, "ABC" would give me ABC etc but how do I trigger Swift to put up it's internal Back Button image. The code below doesn't work but I would have thought is along the right lines.
let backImg: UIImage = UIImage(named: "BACK_BUTTON_DEFAULT_ICON")!
navigationItem.leftBarButtonItem!.setBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)
Has anyone worked out how to do this?
Try to add custom view as back button like as
var backButton = UIButton(frame: CGRectMake(0, 0, 70.0, 70.0))
var backImage = UIImage(named: "backBtn")
backButton.setImage(backImage, forState: UIControlState.Normal)
backButton.titleEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 0.0)
backButton.setTitle("Back", forState: UIControlState.Normal)
backButton.addTarget(self, action: "buttonPressed", forControlEvents: UIControlEvents.TouchUpInside)
var backBarButton = UIBarButtonItem(customView: backButton)
var spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
spacer.width = -15
self.navigationItem.leftBarButtonItems = [spacer,backBarButton]
It will look same as iOS back button
I struggled with this question for a while. Finally I got the back image with the following code:
let backImage = navigationController?.navigationBar.subviews[2].subviews[0].subviews[0].subviews[0] as! UIImageView).image
Before run the code above, make sure the back button is showing. Then you can save backImage to anywhere you want.
Here is the backImage I got.
Here is my solution:
override func viewDidLoad() {
...
let buttonBack = UIBarButtonItem(image: UIImage(named: "backButton"), style: .plain, target: self, action: #selector(buttonSavePressed(_:)))
self.navigationItem.leftBarButtonItem = buttonBack
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 24.0, height: 24.0))
let backImage = UIImage(named: "backButton")
backButton.setImage(backImage, for: .normal)
backButton.setTitle("Back", for:.normal)
if #available(iOS 13.0, *) {
backButton.setTitleColor(.link, for: .normal)
} else {
backButton.setTitleColor(.blue, for: .normal)
}
backButton.addTarget(self, action:#selector(buttonSavePressed(_:)), for: .touchUpInside)
let backBarButton = UIBarButtonItem(customView: backButton)
let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
spacer.width = -15
self.navigationItem.leftBarButtonItems = [spacer,backBarButton]
}
#objc func buttonBackPressed(_ sender: Any) {
...
}
If you want to get the default back button image, the arrow is a class of type _UINavigationBarBackIndicatorView.
Here follows the hack,
UIImage *imgViewBack ;
for (UIView *view in self.navigationController.navigationBar.subviews) {
// The arrow is a class of type _UINavigationBarBackIndicatorView. This is not any of the private methods, so I think
// this is fine for the AppStore...
if ([NSStringFromClass([view class]) isEqualToString:#"_UINavigationBarBackIndicatorView"]) {
// Set the image from the Default BackBtn Imageview
UIImageView *imgView = (UIImageView *) view;
if(imgView){
imgViewBack = imgView.image ;
}
}
}
Try this to replace the back button image:
let back_image = UIImage(named: "btn_back")
self.navigationBar.backIndicatorImage = back_image
self.navigationBar.backIndicatorTransitionMaskImage = back_image
If you don't like to have the "Back" title you can add this too:
self.navigationBar.topItem?.title = ""
My Custom Activity indicator is not overlapping Navigation controller.
Below is my code
func showActivityIndicator(uiView: UIView) {
container.frame = uiView.frame
container.center = uiView.center
container.backgroundColor = UIColorFromHex(0xffffff, alpha: 0.1)
var loadingView: UIView = UIView()
loadingView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
loadingView.center = uiView.center
loadingView.backgroundColor = UIColorFromHex(0x444444, alpha: 0.5)
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 10
var imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("synch-loader", withExtension: "gif")!)
let try = UIImage.animatedImageWithData(imageData!)
var imageView = UIImageView(image: try)
imageView.center = uiView.center
imageView.frame = CGRect(x: uiView.frame.width/4, y: uiView.frame.height/2, width: 500, height: 15)
loadingView.addSubview(imageView)
container.addSubview(loadingView)
uiView.addSubview(container)
actInd.startAnimating()
}
func navigationHandling()
{
if self.navigationController != nil {
self.navigationController?.navigationBar.tintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBar.barTintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBarHidden = false
self.navigationItem.hidesBackButton = true
}
sortingBtn = UIBarButtonItem(image: sortingImg, style: UIBarButtonItemStyle.Done, target: self, action: Selector("sortingPressed:"))
menuBtn = UIBarButtonItem(image: menuImg, style: UIBarButtonItemStyle.Plain, target: self, action : nil)
sortingBtn.tintColor = UIColor.whiteColor()
menuBtn.tintColor = UIColor.whiteColor()
var buttons : NSArray = [menuBtn,sortingBtn]
self.navigationItem.rightBarButtonItems = buttons as [AnyObject]
self.navigationItem.setRightBarButtonItems([menuBtn,sortingBtn], animated: true)
networkLabel.hidden = true
}
I just want to overlap the view on navigation controller so that it don't looks ugly.
I appreciate help!
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
window.addSubview("yourActivityIndicator")
Here add the activity indicator to the window, or pass the window in as the view.
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
showActivityIndicator(window)
The uiView you're passing as parameter to this method
func showActivityIndicator(uiView: UIView)
is your ViewController's view or your UINavigationController's view?
Because if it's your UIViewController's view your custom loading will take it's size and origin, that is under your NavigationBar