Swift how to change backIndicatorImage's position and size - swift

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)
}

Related

titleView of Navigation item moved to the left?

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]
}

Issue making toolbar with custom height | Swift 5

Essentially I have the following toolbar that is currently set to contain two buttons on both the left and right side:
//Select All Toolbar
self.navigationController?.isToolbarHidden = false
self.navigationController?.toolbar.barTintColor = UIColor(named: "tabBarColor")
//self.navigationController?.toolbar.barTintColor = UIColor.white
self.navigationController?.toolbar.sizeToFit() // without this line it doesn't work
self.navigationController?.toolbar.tintColor = UIColor(named:"toolBarRedColor")
var items = [UIBarButtonItem]()
let selectbutton = UIBarButtonItem(title: "Left Button", style: .plain, target: self, action: #selector(printMe))
let unselectbutton = UIBarButtonItem(title: "Right Button", style: .plain, target: self, action: #selector(printMe))
items.append(selectbutton)
items.append( UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil))
items.append(unselectbutton)
self.toolbarItems = items
I would like to expand the height of the tool bar and have tried doing the following:
class CustomToolbar: UIToolbar {
override func sizeThatFits(_ size: CGSize) -> CGSize {
var newSize: CGSize = super.sizeThatFits(size)
newSize.height = 80 // there to set your toolbar height
return newSize
}
}
What is being done incorrectly? The height is not being adjusted.
Try this:
let navBarSize = CGSize(width: navigationController!.navigationBar.bounds.width, height: 200)
override func viewDidLayoutSubviews() {
navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: navBarSize.width, height: navBarSize.height)
}
Hope this helps :)

Navigation Bar don't charge correctly the first time

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
}

Change UIBarButton image from gallery

I have UIBarButton and user can change image just chose photo or gallery image with image picker. My problem is bad scale image.
If I use AspectFit my UIBarButton look like this:
If I use AspectFill my UIBarButton look like this:
and if I try first change size image and after set it, image all time scratched:
This is my code:
func createPhotoBarButton(image: Data) {
let barbtn = UIBarButtonItem()
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")
}
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0))
imageView.image = image?.resizedImage(newSize: CGSize(width: 35, height: 35))?.withRenderingMode(.alwaysOriginal)
// imageView.image = cropToBounds(image: image!, width: 35, height: 35)
// imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = imageView.frame.size.height / 2
imageView.layer.masksToBounds = true
imageView.clipsToBounds = true
self.navigationItem.rightBarButtonItem = barbtn
barbtn.customView = imageView
barbtn.customView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(photoTapped(_:))))
}
And here func for resize image:
func resizedImage(newSize: CGSize) -> UIImage? {
guard size != newSize else { return self }
let hasAlpha = false
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(newSize, !hasAlpha, scale)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Help me plz find the right way to resolving my problem.
As I understand your question. I found a solution.
Try this
func createPhotoBarButton(image: Data) {
let barbtn = UIBarButtonItem()
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0))
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")?.resize(maxWidthHeight: Double(imageView.frame.size.width))
}
imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = imageView.frame.size.height / 2
imageView.layer.masksToBounds = true
imageView.clipsToBounds = true
self.navigationItem.rightBarButtonItem = barbtn
barbtn.customView = imageView
barbtn.customView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(photoTapped(_:))))
}
Resize method
extension UIImage {
func resize(maxWidthHeight : Double)-> UIImage? {
let actualHeight = Double(size.height)
let actualWidth = Double(size.width)
var maxWidth = 0.0
var maxHeight = 0.0
if actualWidth > actualHeight {
maxWidth = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualWidth)
maxHeight = (actualHeight * per) / 100.0
}else{
maxHeight = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualHeight)
maxWidth = (actualWidth * per) / 100.0
}
let hasAlpha = true
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(CGSize(width: maxWidth, height: maxHeight), !hasAlpha, scale)
self.draw(in: CGRect(origin: .zero, size: CGSize(width: maxWidth, height: maxHeight)))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
return scaledImage
}
}
Output
Try to create a custom button with the code below:
func createPhotoBarButton(image: Data) {
let imageBtnContainer = UIButton()
let imageBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")
}
imageBtn.setImage(image, forState: UIControlState.Normal)
imageBtn.frame = CGRectMake(0, 0, 53, 31)
imageBtn.imageView?.contentMode = .scaleAspectFit
imageBtnContainer.addSubview(imageBtn)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: imageBtnContainer)
...
}
You don't need anymore resizedImage(..) function
Here is working code (swift 4)
override func viewDidLoad() {
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
let Button : UIButton = UIButton.init(type: .custom)
Button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
Button.Round = true
Button.setImage(UIImage(named: "photoIcon"), for: .normal)
Button.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
containView.addSubview(Button)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
}
Button Action Here
#objc func btnTapped(_ sender: Any) {
print("Click Event")
}
Extension to Round
extension UIView{
#IBInspectable var Round:Bool{
get{
return false
}
set{
if newValue == true {
self.layer.cornerRadius = self.frame.size.height/2;
self.layer.masksToBounds = true;
}
}
}
}
Output:

How to set the alpha of an UIImage in SWIFT programmatically?

I found a lot solutions here but not for Swift, and I know you can do this with a UIImageView, but in my case i need an programmatically set alpha transparent background image for an UIButton. Best would be an UIImage extension!
let img = UIImage(named: "imageWithoutAlpha")
var imgInsets = UIEdgeInsetsMake(0, 24, 0, 24)
image = image!.resizableImageWithCapInsets(imgInsets)
let myButton = UIButton(frame: CGRect(x: 50, y: 50, width: img!.size.width, height: img!.size.height))
myButton.setBackgroundImage(img, forState: UIControlState.Normal)
myButton.contentEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 20)
myButton.setTitle("Startbutton", forState: UIControlState.Normal)
myButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
myButton.sizeToFit()
view.addSubview(myButton)
Current result:
Desired result:
Luckily I was able to help myself and would like to share with you my solution:
Swift 3
// UIImage+Alpha.swift
extension UIImage {
func alpha(_ value:CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: CGPoint.zero, blendMode: .normal, alpha: value)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
The above new Swift extension I added to my project and then I changed the UIButton example as follows, to have an alpha transparent background image with a transparency of 50%.
let img = UIImage(named: "imageWithoutAlpha")!.alpha(0.5)
let myButton = UIButton()
myButton.setBackgroundImage(img, for: .normal)
The easiest way is to put your UIImage inside a UIImageView and set the alpha there.
let image = UIImage(named: "imageWithoutAlpha")
let imageView = UIImageView(image: image)
imageView.alpha = 0.5
myButton.setBackgroundImage(image, forState: UIControlState.Normal)
Swift 5, iOS 10+
If your app doesn't support operating systems prior to iOS 10 then you can take advantage of the more robust UIGraphicsImageRenderer UIKit drawing API.
extension UIImage {
func withAlpha(_ a: CGFloat) -> UIImage {
return UIGraphicsImageRenderer(size: size, format: imageRendererFormat).image { (_) in
draw(in: CGRect(origin: .zero, size: size), blendMode: .normal, alpha: a)
}
}
}
Usage
let img = UIImage(named: "someImage")?.withAlpha(0.5)
I was able to set the alpha using the following code:
self.imageView.image = UIImageView(image: "image.png")
imageView.alpha = 0.5