Issue making toolbar with custom height | Swift 5 - swift

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

Related

UIToolbar doesn't show again in view when dismissing keyboard in Swift

I have an UIToolbar containing a UITextField. I want to show the toolbar above the keyboard and then display it again when I finish editing inside the textfield.
The issue is that it is working when selecting the textfield. However, the toolbar is disappearing from the view when hiding the keyboard.
What should be done to redisplay it again to my view?
My Swift code is:
Add UITextFieldDelegate
class ATCChatThreadViewController: MessagesViewController, MessagesDataSource, MessageInputBarDelegate, UITextFieldDelegate {
Create ToolBar is as below
func createToolbar(){
//Fixed space
let fixed = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
fixed.width = 10
//Camera
//let img = UIImage(named: "camera-filled-icon")!.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
let img = UIImage.localImage("camera-filled-icon", template: true)
let iconSize = CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30))
let iconButton = UIButton(frame: iconSize)
iconButton.setTitleColor(uiConfig.primaryColor, for: .normal)
iconButton.setBackgroundImage(img, for: .normal)
let cameraItem = UIBarButtonItem(customView: iconButton)
cameraItem.tintColor = uiConfig.primaryColor
iconButton.addTarget(self, action: #selector(cameraButtonPressed), for: .touchUpInside)
//TextField true
textFieldChat = UITextField(frame: CGRectMake(0,0,(self.view.frame.size.width - 100) ,30))
textFieldChat.tintColor = uiConfig.primaryColor
textFieldChat.textColor = uiConfig.inputTextViewTextColor
textFieldChat.backgroundColor = uiConfig.inputTextViewBgColor
textFieldChat.layer.cornerRadius = 14.0
textFieldChat.layer.borderWidth = 0.0
textFieldChat.font = UIFont.systemFont(ofSize: 16.0)
textFieldChat.delegate = self
textFieldChat.attributedPlaceholder = NSAttributedString(string: "Start typing...".localized(), attributes: [NSAttributedString.Key.foregroundColor: uiConfig.inputPlaceholderTextColor])
let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 20))
textFieldChat.leftView = paddingView
textFieldChat.leftViewMode = .always
let textFieldButton = UIBarButtonItem(customView: textFieldChat)
//Fixed space
let fixedTwo = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
fixedTwo.width = 10
//Send Button
let imgSend = UIImage.localImage("share-icon", template: true)
let iconSendSize = CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30))
let sendButton = UIButton(frame: iconSendSize)
sendButton.setTitleColor(uiConfig.primaryColor, for: .normal)
sendButton.setBackgroundImage(imgSend, for: .normal)
let sendItem = UIBarButtonItem(customView: sendButton)
sendItem
.tintColor = uiConfig.primaryColor
sendButton.addTarget(self, action: #selector(sendBtnPressedWith), for: .touchUpInside)
//Flexible Space
// let flexible = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil)
let flexible = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
flexible.width = 10
//Toolbar
var bottomsafeAreaHeight: CGFloat?
if #available(iOS 11.0, *) {
bottomsafeAreaHeight = UIApplication.shared.windows.first{$0.isKeyWindow }?.safeAreaInsets.bottom ?? 0
} else {
// Fallback on earlier versions
bottomsafeAreaHeight = bottomLayoutGuide.length
bottomsafeAreaHeight = UIApplication.shared.keyWindow?.rootViewController?.bottomLayoutGuide.length ?? 0
}
toolbar = UIToolbar(frame: CGRectMake(0,(self.view.frame.size.height - 116 - (bottomsafeAreaHeight ?? 0)),view.frame.width,50))
toolbar.sizeToFit()
toolbar.barTintColor = UIColor.f5f5f5ColorBg()
toolbar.isTranslucent = false
toolbar.tintColor = uiConfig.primaryColor
toolbar.items = [fixed, cameraItem, fixed, textFieldButton,fixedTwo, sendItem,flexible]
view.addSubview(toolbar)
}
// MARK: - UITextFieldDelegate
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
textFieldChat.inputAccessoryView = toolbar
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
view.addSubview(toolbar)
self.toolbar.isHidden = false
return true
}
if only chat etxfield is using toolbar then replace line:
view.addSubview(toolbar)
with
textFieldChat.inputAccessoryView = toolbar
remove both methods textFieldShouldBeginEditing and textFieldShouldEndEditing

How can I escape my numpad/keyboard for my 30 textfield inputs?

I just implemented about 30 textfield inputs and after running my app I realized that I am not able to escape the numpad in anyway?? Has anyone figured out a simple solution to escape/remove the numbpad/keyboard?? I found the solution of adding a toolbar to the keyboard but that would require me to do that 30 times which doesn't sound efficient to me.
Use this
extension UITextField {
#IBInspectable var doneAccessory: Bool {
get {
return self.doneAccessory
}
set (hasDone) {
if hasDone {
addDoneButtonOnKeyboard()
}
}
}
func addDoneButtonOnKeyboard() {
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))
let items = [flexSpace, done]
doneToolbar.items = items
doneToolbar.sizeToFit()
self.inputAccessoryView = doneToolbar
}
#objc func doneButtonAction() {
self.resignFirstResponder()
}
}
and add this single line to your text fields
textField.doneAccessory = true

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)

iOS: adding buttons to Toolbar programmatically

I need to create Toolbar and add buttons programmatically. I will have different sets of buttons for diferent screens.
That's easy.
Also, I need to center those buttons. They should have equal space between them.
And also I need that all those buttons separate screen width only between themselfs. Like, I have 5 buttons, total screen width is 300, so each button will have width 60. I am not sure how to do that, i tried dirrenrt things but they wasn't centered or hadn't such width. Any ideas how to do that?
class OptionsView: UIView {
#IBOutlet weak var toolbar: UIToolbar!
var width: CGFloat {
return 0//UIScreen.main.bounds.width/5 //was trying to calculate width , but it did not work
}
override func awakeFromNib() {
super.awakeFromNib()
toolbar.isTranslucent = true
toolbar.setBackgroundImage(UIImage(), forToolbarPosition: UIBarPosition.any, barMetrics: UIBarMetrics.default)
toolbar.setShadowImage(UIImage(), forToolbarPosition: UIBarPosition.any)
toolbar.barTintColor = .white
backgroundColor = .clear
}
func addAirPlay(target: Any?, action: Selector) {
let normalImage = UIImage(named: "player-airplay")
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: width, height: 100)
button.setImage(normalImage, for: UIControlState())
button.addTarget(target, action: action, for: .touchUpInside)
let item = UIBarButtonItem(customView: button)
//item.width = width //was trying to play with that
var items = toolbar.items
items?.append(item)
toolbar.items = items
toolbar.reload()
}
func addOrientation(target: Any?, action: Selector) {
let button = UIButton(type: .custom)
button.tag = orientationTag
button.frame = CGRect(x: 0, y: 0, width: width, height: 100)
button.addTarget(target, action: action, for: .touchUpInside)
let item = UIBarButtonItem(customView: button)
//item.width = width
var items = toolbar.items
items?.append(item)
toolbar.items = items
toolbar.reload()
reloadOrientation()
}
func addFlexibleSpace() {
let item = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
var items = toolbar.items
items?.append(item)
toolbar.items = items
toolbar.reload()
}
Creating:
optionsView = OptionsView.loadFromNib()
playerView.addSubview(optionsView)
optionsView.snp.makeConstraints { (make) in
make.leading.trailing.top.bottom.equalTo(self.optionsPlaceholderView)
}
// optionsView.addFlexibleSpace() //was trying that as well
optionsView.addAirPlay(target: self, action: #selector(airplayButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addOrientation(target: self, action: #selector(orientationButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addFave(target: self, action: #selector(faveButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addExtra(target: self, action: #selector(showExtraButtonAction(_:)))
optionsView.addFlexibleSpace()
optionsView.addScenes(target: self, action: #selector(sceneButtonAction(_:)))
// optionsView.addFlexibleSpace()

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)