Search code examples
swift3uitextviewuitoolbaruikeyboardxcode8.2

Adding a 2nd UIToolBar for Keyboard used with UITextViews


I currently have a working UIToolbar where I'm putting extra buttons above the keyboard when using a UITextField but I was wanting to make a 2nd UIToolbar type for above a UITextView. When I tried copying my code and modifying it to be how I'd like it to look, it doesn't show up at all. I'm not sure if I'm doing something wrong or if it has something to do with the NotificationCenter and addObserver I'm using. FYI, the overall class is called AddRecipeDirectionVC: UIViewController, UITextViewDelegate if that is needed at all.

So here is the observer code I'm adding into my viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()

    //...Other Code...

    NotificationCenter.default.addObserver(self, selector: #selector(AddRecipeDirectionVC.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}

Originally, I thought I had to add this Observer on each UIViewController, but I'm starting to think this code I'm using could just be put in the initial VC and it would carry out for the rest of the project (currently, I'm using that code in ever VC where I'm adding the Toolbar)

Next, I have the textViewDidBeginEditing function where I think the keyboard toolbar is being added.

func textViewDidBeginEditing(_ textView: UITextView) {

    if (textView.textColor == UIColor.lightGray) {
        textView.text = nil
        textView.textColor = UIColor.black
    }
    self.keyboardToolbar(textView: textView) //Adding Keyboard
}

And then finally, I have keyboardWillShow and keyboardToolbar functions

func keyboardWillShow(notification: Notification) {

    let keyFrame = ((notification as NSNotification).userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    let keyHeight = keyFrame.size.height

    self.bottomSpace.constant = keyHeight + 12
}

func keyboardToolbar(textView: UITextView) {

    let toolbar: UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
    toolbar.barStyle = UIBarStyle.default
    toolbar.bounds.size.height = 28

    let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)

    let done: UIBarButtonItem = UIBarButtonItem(image:  #imageLiteral(resourceName: "Done Check"), style: UIBarButtonItemStyle.done, target: self, action: #selector(AddRecipeIngredientVC.doneButtonAction))
    done.tintColor = UIColor.aqua(alpha: 1.0)

    let clear: UIBarButtonItem = UIBarButtonItem(title: "Clear", style: UIBarButtonItemStyle.plain, target: self, action: #selector(AddRecipeDirectionVC.clearButtonAction))
    clear.tintColor = UIColor.darkAqua(alpha: 1)

    var items = [UIBarButtonItem]()

    items.append(clear)
    items.append(flexSpace)
    items.append(done)

    toolbar.items = items
    toolbar.sizeToFit()

    textView.inputAccessoryView = toolbar    }

func doneButtonAction() {

    self.directionText.resignFirstResponder()
    self.bottomSpace.constant = 12
}

func clearButtonAction() {

    directionText.text = ""
}

As far as I can tell, I'm doing everything the same as in the other VC's, so it seems like it should be working, but nothing ever shows up. Let me know if any additional code needs to be added.

Thank you in advanced for any help anyone can give me :)


Solution

  • After much googling, I found out that the keyboardToolbar code had to be put in textViewShouldBeginEditing not textViewDidBeginEditing. From what I understand, with a UITextView the layout has already been set once it gets to textViewDidBeginEditing, hence the reason I wasn't seeing it. This is the code I ended up using that did the job. Everything else is the same beside what is shown below.

    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
    
        self.keyboardToolbar(textView: textView)
        return true
    }
    
    func textViewDidBeginEditing(_ textView: UITextView) {
    
        if (textView.textColor == UIColor.lightGray) {
            textView.text = nil
            textView.textColor = UIColor.black
        }
    }