0

I'm trying to add a simple "Done" button to my UIPickerView programmatically, without using storyboards.

When I try to add toolBar as a subview of the UIPickerView, the toolbar doesn't even show up and I get some constraint related errors.

Any idea on how I can add the button to the PickerView?

Here is a snippet of my code:

var timerImage = UIButton()
var timer = Timer()
var timerDisplayed = 0
let image1 = UIImage(named: "stopwatch")
let timePicker = UIPickerView()
let timeSelect : [String] = ["300","240","180","120","90","60","45","30","15"]

let toolBar = UIToolbar()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ThirdViewController.dismissKeyboard))

func pickerViewConstraints(){
    timePicker.anchor(top: nil, leading: view.safeAreaLayoutGuide.leadingAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, trailing: view.safeAreaLayoutGuide.trailingAnchor)
}

@objc func timeClock(){
    toolBar.setItems([doneButton], animated: true)
    toolBar.sizeToFit()
    toolBar.isTranslucent = false
    toolBar.isUserInteractionEnabled = true
    toolBar.barStyle = .default

    view.addSubview(timePicker)
    timePicker.addSubview(toolBar)
    pickerViewConstraints()
    timePicker.backgroundColor = .white

    DispatchQueue.main.async {
        self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.Action), userInfo: nil, repeats: true)
        self.timerImage.setImage(nil, for: .normal)
    }
}
mkrieger1
  • 19,194
  • 5
  • 54
  • 65

3 Answers3

1

No, you don't need to add constraints. It can be like :

let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(title: buttonTitle, style: .done, target: self, action: #selector(doneButtonAction))
let cancelButton = UIBarButtonItem(title: cancelTitle, style: .plain, target: self, action: #selector(cancelButtonAction))
let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 44))
barAccessory.barStyle = .default
barAccessory.isTranslucent = true
barAccessory.barTintColor = .blue
barAccessory.setItems([cancelButton, space, doneButton], animated: false)
picker.addSubview(barAccessory)
self.view.bringSubviewToFront(picker)

Hope it helps...

Picode
  • 1,140
  • 1
  • 6
  • 12
  • 1
    This is what fixed it for me. Thank you. 'let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 44))' –  Jan 21 '20 at 07:49
0

You need to set a delegate of type UIPickerViewDelegate to your picker view. In this delegate, implement the delegate method pickerView:viewForRow:forComponent:reusingView

to provide your custom view for the picker item.

For the custom view you provide, you can design it however you want, including adding the button.

Li Mengran
  • 367
  • 1
  • 5
0

It looks like it's just a few minor issues here. Here's how I've done it prior:

    override func viewDidLoad() {
    super.viewDidLoad()

    createToolbar()
}
    // Toolbar for "done"
    func createToolbar() {
        let toolBar = UIToolbar()
        toolBar.sizeToFit()


        let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(PageOneViewController.dismissKeyboard))

        toolBar.setItems([doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true

        // Makes toolbar apply to text fields
        educationText.inputAccessoryView = toolBar
        politicalText.inputAccessoryView = toolBar
        drinkingText.inputAccessoryView = toolBar
        heightText.inputAccessoryView = toolBar
        schoolInput.inputAccessoryView = toolBar
    }

@objc func dismissKeyboard() {
        view.endEditing(true)
    }

It seems like you haven't technically "called" the toolbar / done button, unless I'm just not seeing that part of the code. Also I've nested the "done" code inside of the function.

If you're using text fields then you should be able to follow to "educationText.inputAccessoryView = toolBar" format to apply all of the code above to each text field (education, politics, drinking, etc). I hope this helps! Good luck.

Kasey
  • 374
  • 2
  • 12