【问题标题】:Swift - creating a UIPickerView within a UIStackView PROGRAMMATICALLYSwift - 在 UIStackView 中以编程方式创建 UIPickerView
【发布时间】:2020-10-18 14:11:00
【问题描述】:

总的来说,我是 swift 和 iOS 开发的完全初学者,所以请放轻松 :)
在我的应用程序中,我有一个水平 StackView。
在那个 StackView 中 - 我有一个 label 和一个 button,现在我想添加一个 PickerView 将从一些选项列表中填充.
我一直在谷歌搜索和阅读线程,但我得到的最接近的是让 PickerView 显示其位置(使用一些背景颜色)但 内部没有实际值
这是我创建和自定义 StackView 组件的代码:

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)
    }
    ...
}

然后,我通过调用 setupSingleInput() 将这些组件添加到我的 Horizo​​ntal StackView:

class SingleReportInputStackView: UIStackView {
    ...
    private func setupSingleInput() {
        let (myLabel, myButton, myPicker) = getObjects()
        self.addArrangedSubview(myLabel)
        self.addArrangedSubview(myButton)
        self.addArrangedSubview(myPicker)
        self.translatesAutoresizingMaskIntoConstraints = false
    }
    ...
}

正如我所说,我可以看到标签、按钮和 PickerView 的白色背景(看起来像一个空白的白色矩形)。

顺便说一句,我没有故事板(如果这还不明显的话)-我正在以编程方式创建 UI。

有人可以帮帮我吗?为什么我的数据数组没有正确填充我的 PickerView?

【问题讨论】:

    标签: ios swift uikit uipickerview uistackview


    【解决方案1】:

    总的来说,我是 swift 和 iOS 开发的初学者 ...

    我建议从简单一点开始...在 func 中嵌入 class 几乎肯定不是这里的方法。

    最大的问题是你在 getObjects() 函数中创建了一个 MyPicker 的实例,但是你从那个类返回了一个 UI 元素,并且类实例消失了——它超出了范围

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

    所以,您返回了一个UIPickerView,但它不再有任何代码(它的委托和数据源)支持它。

    这里有一个快速修改:

    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
            }
        }
        
    }
    

    和一个示例视图控制器来尝试:

    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),
            ])
            
        }
        
    }
    

    该代码将为您提供以下结果:

    【讨论】:

    • 你是个传奇,谢谢!不过那个范围的东西太奇怪了……我有 python 背景,我习惯于在函数(甚至类)周围传递对象,而不用担心它们最初定义的范围
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多