UIToolbar doesn't show again in view when dismissing keyboard in Swift - 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

Related

implement "done" button in UIToolBar to close UIDatePicker and ToolBar

I want to close my uidatepicker and my toolbar by pressing a "done"-button in my toolbar.
I am using a label instead of a textfield so the common solutions don't work.
I have tried:
#IBAction func ButtonPressed(_ sender: UIButton) {
print("hallo")
let picker = UIDatePicker()
picker.backgroundColor = .white
picker.datePickerMode = .date
//picker.sizeToFit()
var datumComponents = DateComponents()
datumComponents.year = 2019
datumComponents.month = 6
datumComponents.day = 1
let meinStartKalender = Calendar.current
let StartDatum = meinStartKalender.date(from: datumComponents)
picker.minimumDate = StartDatum
picker.maximumDate = Date()
let pickerSize1 = myView.bounds.width
picker.addTarget(self, action: #selector(dueDateChanged(sender:)), for: UIControl.Event.valueChanged)
picker.frame = CGRect(x:0.0, y: self.view.frame.height - 300 , width: pickerSize1, height: 200)
self.view.addSubview(picker)
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.backgroundColor = .red
toolBar.frame = CGRect(x:0.0, y: self.view.frame.height - 340 , width: pickerSize1, height: 40)
self.view.addSubview(toolBar)
what I've found already:
add:
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.donePressed(_:)))
toolBar.setItems([doneButton], animated: false)
but the error message says:
Value of type 'ViewController' has no member 'donePressed'
how can I change the action or how can I implement a button that works?
Add this in your code
#objc
func donePressed(_ sender: UIButton) {
}

How to add UIImageView to navigation bar in swift?

I have this code that adds a rounded border around a UIImage using UIImageView and I've used UITapGestureRecognizer to let the user tap on the button:
var profilePicture = UIImageView()
func setupUserProfileButton() {
let defaultPicture = UIImage(named: "profilePictureSmall")
profilePicture = UIImageView(image: defaultPicture)
profilePicture.layer.cornerRadius = profilePicture.frame.width / 2
profilePicture.clipsToBounds = true
profilePicture.layer.borderColor = UIColor.black.cgColor
profilePicture.layer.borderWidth = 1
// Letting users click on the image
profilePicture.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(profilePictureTapped))
profilePicture.addGestureRecognizer(tapGesture)
}
How can I add this to the left side of a navigation bar? Is it possible? And I don't think the tap gesture is needed if I can add the ImageView to the navigation bar as a barButtonItem, so you can ignore that. I kinda found some similar questions but they were in objective C and none of what I tried worked.
Here is what I came up with based on an answer:
import UIKit
import Firebase
class CreateStoryPage: BaseAndExtensions {
let userProfileButton = UIButton(type: .custom)
override func viewDidLoad() {
super.viewDidLoad()
// Call all the elements
setupUserProfileButton()
}
// MARK:- Setups
// Setup the user profile button
func setupUserProfileButton() {
userProfileButton.setImage(#imageLiteral(resourceName: "profilePictureSmall.png"), for: .normal)
userProfileButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
userProfileButton.addTarget(self, action: #selector(profilePictureTapped), for: .touchUpInside)
let userProfileView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
userProfileView.layer.cornerRadius = 14
userProfileView.backgroundColor = .red
userProfileView.addSubview(userProfileButton)
let leftNavBarItem = UIBarButtonItem(customView: userProfileView)
self.navigationItem.setLeftBarButton(leftNavBarItem, animated: true)
}
// if user taps on profile picture
#objc func profilePictureTapped() {
let userProfilePage = UserProfilePage()
present(userProfilePage, animated: true, completion: nil)
}
}
Try this;
private func setupRightItem() {
let userProfileButton = UIButton(type: .custom)
userProfileButton.imageView?.contentMode = .scaleAspectFill
userProfileButton.clipsToBounds = true
userProfileButton.addTarget(self, action: #selector(profilePictureTapped), for: .touchUpInside)
userProfileButton.setImage(#imageLiteral(resourceName: "profilePictureSmall.png"), for: .normal)
userProfileButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: userProfileButton)
userProfileButton.widthAnchor.constraint(equalToConstant: 30).isActive = true
userProfileButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
}
#objc private func goProfile() {
/// -> Action
}
let navBtn = UIButton(type: .custom)
navBtn.setImage("yourImage", for: .normal)
navBtn.frame = CGRect(x: 0, y: 0, width: 28, height: 28)
navBtn.addTarget(self, action: #selector(self.openProfile(_:)), for: .touchUpInside)
let view = UIView(frame: CGRect(x: 0, y: 0, width: 28, height: 28))
view.cornerRadius = 14
view.backgroundColor = Global.colorBlue
view.addSubview(navBtn)
let leftNavBarItem = UIBarButtonItem(customView: view)
self.navigationItem.setLeftBarButton(leftNavBarItem, animated: true)
#objc
func openProfile(_ sender: UIButton) {
}

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

UIToolbar with custom height

I'm trying trying to change my toolbar that I added Programmatically. but it didn't reflect. so any help
this is my code. and in the viewController I embed the view from UINavigation Controller
class ViewController: UIViewController,UIToolbarDelegate {
private var toolItems : [UIBarButtonItem] = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
navigationController?.isToolbarHidden = false
let height: CGFloat = 130
let bounds = self.navigationController?.toolbar.bounds
navigationController?.toolbar.barTintColor = UIColor(red: 0.0/42, green: 0.0/42, blue: 0.0/56, alpha: 1)
navigationController?.toolbar.tintColor = UIColor.white
navigationController?.toolbar.frame = CGRect(x: 0, y: self.view.frame.height - 80, width: self.view.frame.width, height: (bounds?.height)! + height)
navigationController?.toolbar.isTranslucent = false
navigationController?.toolbar.heightAnchor.constraint(equalToConstant: (bounds?.height)! + height).isActive = true
navigationController?.toolbar.sizeToFit()
let btn_Tracking = UIButton(type: .custom)
btn_Tracking.setImage(UIImage(named: "icon-trackingtabbed#2x"), for: .normal)
btn_Tracking.sizeToFit()
let trackingItem = UIBarButtonItem(customView: btn_Tracking)
///Sign
let btn_sign = UIButton(type: .custom)
btn_sign.setImage(UIImage(named: "icon-trackingtabbed#2x"), for: .normal)
btn_sign.sizeToFit()
let sginItem = UIBarButtonItem(customView: btn_sign)
let fixedSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
fixedSpace.width = 10.0
let flexibleSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
self.toolbarItems = [flexibleSpace,sginItem,flexibleSpace,trackingItem,flexibleSpace]
}
}

AddGesture different in Swift 3?

I have no idea why my code isn't working :
let profileImageView: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "gameofthrones_splash")
image.translatesAutoresizingMaskIntoConstraints = false
image.contentMode = .scaleAspectFill
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView))
image.addGestureRecognizer(tapGesture)
image.isUserInteractionEnabled = true
return image
}()
This imageView is loaded in the ViewDidLoad (I can see it)
func handleSelectProfileImageView() {
print("123")
}
But nothing get returned in the console when I'm tapping on it ! WTF?
It's in the target. This works when place in the viewDidLoad():
profileImageView.frame = CGRect(x: 60, y: 60, width: 70, height: 70)
view.addSubview(profileImageView)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView))
profileImageView.addGestureRecognizer(tapGesture)
The target is "self", which is the UIViewController (not the UIImageView). In most cases (I'm sure there are outliers) you want to record a gesture in a view, but work with the gesture in a view controller.
Okay the solution was quite simple actually. You have to make it a lazy var instead of a let.
lazy var profileImageView: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "gameofthrones_splash")
image.translatesAutoresizingMaskIntoConstraints = false
image.contentMode = .scaleAspectFill
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView))
image.addGestureRecognizer(tapGesture)
image.isUserInteractionEnabled = true
return image
}()
Swift 3.0:
There was some error I removed it -
Put this code in viewdidLoad
override func viewDidLoad() {
super.viewDidLoad()
var profileImageView:UIImageView {
var image = UIImageView()
image.backgroundColor = UIColor.red;
image.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
image.translatesAutoresizingMaskIntoConstraints = false
image.contentMode = .scaleAspectFill
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView))
image.addGestureRecognizer(tapGesture)
image.isUserInteractionEnabled = true
return image
}
view.addSubview(profileImageView);
// Do any additional setup after loading the view.
}
func handleSelectProfileImageView() {
print("123")
}
Just to test I removed the image, you can add it. But it's working fine.
I fixed this issue using an UIButton ->
let profileImageView: UIButton = {
let iv = UIButton()
let image = UIImage(named: "r2d2")
iv.setImage(image, for: .normal)
iv.translatesAutoresizingMaskIntoConstraints = false
iv.addTarget(self, action: #selector(selectProfileImage), for: .touchUpInside)
iv.isUserInteractionEnabled = true
return iv
}()
#objc func selectProfileImage(){
print("Hello")
}