I'm trying to create a UIPickerView programmatically and display it's rows within an action sheet. However, nothing seems to be working. Here is a simplified example of similar non-working code:
import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
let array = ["one","two","three","four","five"]
var controller: UIAlertController?
var pickerView = UIPickerView(frame: CGRectMake(0, 15, 304, 0))
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
controller = UIAlertController(title: "Choose Category", message: "\n\n\n\n\n\n\n\n", preferredStyle: .ActionSheet)
let doneAction = UIAlertAction(title: "Done", style: .Default, handler: nil)
controller!.addAction(doneAction)
pickerView.delegate = self
pickerView.dataSource = self
}
@IBAction func buttonPressed(sender: AnyObject) {
controller!.view.addSubview(self.pickerView)
self.presentViewController(controller!, animated: true, completion: nil)
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return array.count
}
func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 50.0
}
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let view = UIView(frame: CGRectMake(0, 0, 100, 70))
let label = UILabel(frame: CGRectMake(50, 5, 100, 60))
label.text = array[row] as String
view.insertSubview(label, atIndex: 1)
return view
}
}
When the button is pressed, this is the output:
As you can see, the action sheet is not being populated with the array values. This was all working properly before the I upgraded to iOS 9 and Swift 2.0. I've used print
to make sure the pickerView methods are being called which they are and even using print
to check the value of label
and view
and they are there. Can anyone either guide me in a direction or explain what is causing this to not be displayed?
Also: Another funky thing is how these methods are being called. If I press the button once, this is the order of every method call that happens:
numberOfComponentsInPickerView:
numberOfComponentsInPickerView:
rowHeightForComponent:
rowHeightForComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfComponentsInPickerView:
numberOfRowsInComponent:
viewForRow:
viewForRow:
numberOfComponentsInPickerView:
rowHeightForComponent:
rowHeightForComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
numberOfRowsInComponent:
viewForRow:
viewForRow:
viewForRow:
viewForRow:
viewForRow:
You're not supposed to modify the view hierarchy of a UIAlertController. Even if you could get it to work that way, you risk Apple breaking it anytime there's an update and you'd have to keep finding new workarounds to make it work. You may want to consider putting your picker in a view controller and presenting it as a UIModalPresentationPopover
.
If you're using it with a responder subclass like a text field or a custom one you make, you can also make a view that looks like the action sheet with a picker and set it as the inputView
of the responder.