Swift UIBarButtonItem position that was created programatically - swift

I create a button using SwiftIcons, but the position of the icon is not correct. I add a negative width to fix it:
let menuButton = UIBarButtonItem()
menuButton.setIcon(icon: .ionicons(.chevronLeft), iconSize: 24, color: .white, cgRect: CGRect(x: 0, y: 0, width: 24, height: 24), target: self, action: #selector(menuButtonClick))
let negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
negativeSpacer.width = -13.7;
self.navigationItem.leftBarButtonItems = [negativeSpacer, menuButton]
This works for iOS 10 or lower, but on iOS 11 the width does not take negative values.
Image
How can I fix this?
Answer:
let menuButton = UIBarButtonItem(title: "", style: .plain, target: self, action: #selector(menuButtonClick))
menuButton.image = UIImage.init(icon: .ionicons(.chevronLeft), size: CGSize(width: 24, height: 24))
menuButton.imageInsets = UIEdgeInsetsMake(0, -13.7, 0, 0)
self.navigationItem.leftBarButtonItem = menuButton

Maybe you can try by modifying edgeInsets for your button with this method :
UIEdgeInsets UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right);
It allows you to add some padding on your barButtonItem.
Here is how you can use it with your actual code :
negativeSpacer.imageInsets = UIEdgeInsetsMake(0, -13.7, 0, 0);

Related

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

How to make a toolbar be attached to bottom iOS Swift

I have a ploblem with tab bar and navigation bar. There's a toolbar I need to display on top of the tabbar, but attached to the very bottom.
For now I'm getting this:
My code is:
private func showToolBar() {
tabBarController?.tabBar.isHidden = true
navigationController?.setToolbarHidden(false, animated: true)
let archiveButton = UIBarButtonItem(image: #imageLiteral(resourceName: "deactivateIcons"), style: .plain, target: self, action: #selector(archive))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
let refreshButton = UIBarButtonItem(image: #imageLiteral(resourceName: "changeStatusIcons"), style: .plain, target: self, action: #selector(refresh))
archiveButton.tintColor = Colors.Purple
refreshButton.tintColor = Colors.Purple
setToolbarItems([archiveButton, flexibleSpace, refreshButton], animated: true)
navigationController?.toolbar.setShadowImage(UIImage(), forToolbarPosition: .bottom)
}
So the toolbar appears exactly on top of the tabbar. How to solve this? Thanks in advance!
Try this:
put that code in the last line of your showToolBar() function
let screenSize: CGRect = UIScreen.main.bounds
navigationController?.toolbar.frame = CGRect(x: 0, y: screenSize.height - tabBarHeight - 50, width: screenSize.width, height: 50)

Done Toolbar on UIPickerView

So I have a button on a page when clicked I am opening up a picker view. I have populated the picker view with the months. I added a toolbar but whenever I try to select it just scrolls the picker view to the top.
monthPicker = UIPickerView(frame: CGRect(x: 0, y: self.view.frame.size.height- monthPicker.frame.size.height, width: self.view.frame.size.width, height: monthPicker.frame.size.height))
monthPicker.delegate = self
monthPicker.dataSource = self
monthpickerData = ["January","February","March","April","May","June","July","August","September","October","November","December"]
monthPicker.backgroundColor = UIColor.white
//
let btnDone = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.monthdoneButtonAction))
let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: monthPicker.frame.size.width, height: 44))
barAccessory.barStyle = .default
barAccessory.isTranslucent = false
barAccessory.items = [flexiblespace,btnDone]
monthPicker.addSubview(barAccessory)
It seems like UIPickerView is not letting its children receive touch events. If you are showing this in conjunction with UITextField you can use it's inputView and inputAccessoryView to acheive the same. Alternatively you can create a top level container UIView to hold both toolbar and picker view like this:
let picker = UIView(frame: CGRect(x: 0, y: view.frame.height - 260, width: view.frame.width, height: 260))
// Toolbar
let btnDone = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.monthdoneButtonAction))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelClick))
let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: picker.frame.width, height: 44))
barAccessory.barStyle = .default
barAccessory.isTranslucent = false
barAccessory.items = [cancelButton, spaceButton, btnDone]
picker.addSubview(barAccessory)
// Month UIPIckerView
monthPicker = UIPickerView(frame: CGRect(x: 0, y: barAccessory.frame.height, width: view.frame.width, height: picker.frame.height-barAccessory.frame.height))
monthPicker.delegate = self
monthPicker.dataSource = self
monthpickerData = ["January","February","March","April","May","June","July","August","September","October","November","December"]
monthPicker.backgroundColor = UIColor.white
picker.addSubview(monthPicker)

Swift constraint error when adding UINavigationBar

I am trying to add a custom navigation bar to my app, but whenever it loads I get the 'Unable to simultaneously satisfy constraints' error. I can't seem to programatically remove any of the constraints - and I definitely haven't added any.
Console Output:
"<NSLayoutConstraint:0x600000092750 UILabel:0x7ffc40507d20'Configure'.firstBaseline == UILayoutGuide:0x6000007b18e0'TitleView(0x7ffc40503120)'.top + 23 (active)>",
"<NSLayoutConstraint:0x600000092840 UILabel:0x7ffc40507d20'Configure'.top >= UILayoutGuide:0x6000007b18e0'TitleView(0x7ffc40503120)'.top (active)>"
App Delegate:
self.window = UIWindow(frame: UIScreen.main.bounds)
let nav1 = UINavigationController(navigationBarClass: CustomNavBar.self, toolbarClass: nil)
let mainView = TableViewController()
nav1.viewControllers = [mainView]
self.window!.rootViewController = nav1
self.window!.makeKeyAndVisible()
CustomNavBar Class:
self.frame.size.height = 60
self.backgroundColor = appColour
self.tintColor = UIColor.white
self.titleTextAttributes = [
NSForegroundColorAttributeName : UIColor.white,
NSFontAttributeName : UIFont(name: "Avenir-Heavy", size: 30)!
]
self.setTitleVerticalPositionAdjustment(-5, for: .default)
ViewController:
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(start))
navigationItem.rightBarButtonItem!.imageInsets = UIEdgeInsets(top: -7, left: 0, bottom: 0, right: 0)
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "Folder")!, style: .plain, target: self, action: #selector(viewSaved))
navigationItem.leftBarButtonItem!.imageInsets = UIEdgeInsets(top: -7, left: 0, bottom: 0, right: 0)
self.title = "Configure"
I just can't figure out what to do.
Thanks in advance!
The issue is with your font-size in your CustomNavBar Class, reduce the font size until you don't get the constraint error.
self.titleTextAttributes = [
NSForegroundColorAttributeName : UIColor.white,
NSFontAttributeName : UIFont(name: "Avenir-Heavy", size: <30>)!
]

How can I add UIToolbar to UIPickerView without using UITextField?

I have used UIPickerView without UITextField. After user tap on button, UIPickerView will display.
Anyway, I have no idea how to dismiss UIPickerView. I have tried to set inputAccessoryView with UIToolbar but the complier said it's get-only property.
My code:
let toolbar = UIToolbar()
toolbar.barStyle = UIBarStyle.default
toolbar.isTranslucent = true
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(RegisterViewController.pickerDoneButton))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: self, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(RegisterViewController.pickerCancelButton))
toolbar.setItems([cancelButton, spaceButton, doneButton], animated: true)
toolbar.isUserInteractionEnabled = true
pickerView.inputAccessoryView = toolbar
Error: Cannot assign to property: 'inputAccessoryView' is a get-only property
Try to add subview to the UIPickerView
It seems like UIPickerView is not letting its children receive touch events. If you want to add toolbar to pickerview without textfield you can create a top level container UIView to hold both toolbar and picker view like this:
let picker = UIView(frame: CGRect(x: 0, y: view.frame.height - 260, width: view.frame.width, height: 260))
// Toolbar
let btnDone = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.monthdoneButtonAction))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelClick))
let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: picker.frame.width, height: 44))
barAccessory.barStyle = .default
barAccessory.isTranslucent = false
barAccessory.items = [cancelButton, spaceButton, btnDone]
picker.addSubview(barAccessory)
// Month UIPIckerView
monthPicker = UIPickerView(frame: CGRect(x: 0, y: barAccessory.frame.height, width: view.frame.width, height: picker.frame.height-barAccessory.frame.height))
monthPicker.delegate = self
monthPicker.dataSource = self
monthpickerData = ["January","February","March","April","May","June","July","August","September","October","November","December"]
monthPicker.backgroundColor = UIColor.white
picker.addSubview(monthPicker)