I'm a complete beginner to swift & iOS dev in general, so be easy on me :)
In my app, I have a horizontal StackView.
Within that StackView - I have a label and a button , and now I would like to add a PickerView that would be populated from some list of options .
I've been googling and reading threads, but the closest I've gotten was getting the PickerView to show its position (using some background color) but with no actual values inside .
This is the code where I create and customize my StackView's components:
class SingleReportInputStackView: UIStackView {
... // creating and customizing my StackView
private func getObjects() -> (UILabel, UIButton, UIPickerView) {
let myLabel: UILabel = {
... // creating UILabel
}()
let myButton: UIButton = {
... // creating UIButton
}()
class MyPicker: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
let dataArray = ["English", "Maths", "History", "German", "Science"]
let UIPicker: UIPickerView = UIPickerView()
override init() {
super.init()
self.UIPicker.delegate = self
self.UIPicker.dataSource = self
self.UIPicker.backgroundColor = UIColor.white
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let row = dataArray[row]
return row
}
}
let myPicker = MyPicker()
return (myLabel, myButton, myPicker.UIPicker)
}
...
}
Then, I add those components to my Horizontal StackView by calling setupSingleInput()
:
class SingleReportInputStackView: UIStackView {
...
private func setupSingleInput() {
let (myLabel, myButton, myPicker) = getObjects()
self.addArrangedSubview(myLabel)
self.addArrangedSubview(myButton)
self.addArrangedSubview(myPicker)
self.translatesAutoresizingMaskIntoConstraints = false
}
...
}
As I've said, I can see the label, the button and the PickerView's white background (looks like an empty, white rectangle).
BTW, I don't have a storyboard (if that wasn't obvious already) - I'm creating the UI programatically.
Can someone help me out? Why is my PickerView not being properly populated by my dataArray?
I'm a complete beginner to swift & iOS dev in general ...
I'd recommend starting a bit simpler... embedding a class
inside a func
is almost certainly not the way to go here.
The biggest problem is that you create an instance of MyPicker
inside your getObjects()
func, but then you return a UI element from that class, and the class instance goes away -- it goes out of scope :
private func getObjects() -> (UILabel, UIButton, UIPickerView) {
// ... all the stuff you're doing in here
let myPicker = MyPicker()
// as soon as you return, myPicker no longer exists!!!
return (myLabel, myButton, myPicker.UIPicker)
}
So, you have returned a UIPickerView
, but it no longer has any code (its Delegate and DataSource) backing it.
Here's a quick modification:
class SingleReportInputStackView: UIStackView {
private var myPicker: MyPicker!
override init(frame: CGRect) {
super.init(frame: frame)
setupSingleInput()
}
required init(coder: NSCoder) {
super.init(coder: coder)
setupSingleInput()
}
private func setupSingleInput() {
let (myLabel, myButton) = getObjects()
myPicker = MyPicker()
self.addArrangedSubview(myLabel)
self.addArrangedSubview(myButton)
self.addArrangedSubview(myPicker.UIPicker)
self.translatesAutoresizingMaskIntoConstraints = false
}
private func getObjects() -> (UILabel, UIButton) {
let myLabel: UILabel = {
let v = UILabel()
v.text = "The Label"
return v
}()
let myButton: UIButton = {
let v = UIButton(type: .system)
v.setTitle("The Button", for: [])
return v
}()
return (myLabel, myButton)
}
private class MyPicker: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
let dataArray = ["English", "Maths", "History", "German", "Science"]
let UIPicker: UIPickerView = UIPickerView()
override init() {
super.init()
self.UIPicker.delegate = self
self.UIPicker.dataSource = self
self.UIPicker.backgroundColor = UIColor.white
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let row = dataArray[row]
return row
}
}
}
and a sample view controller to try it:
class UriYakirViewController: UIViewController {
let singleReportStack = SingleReportInputStackView()
override func viewDidLoad() {
super.viewDidLoad()
// a yellow-ish background so we can see the white picker view frame
view.backgroundColor = UIColor(red: 1.0, green: 0.8, blue: 0.5, alpha: 1)
view.addSubview(singleReportStack)
singleReportStack.axis = .vertical
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
singleReportStack.centerXAnchor.constraint(equalTo: g.centerXAnchor),
singleReportStack.centerYAnchor.constraint(equalTo: g.centerYAnchor),
])
}
}
That code will give you this result:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.