在UIPickerView中创建3列,也使用追加功能

时间:2018-04-24 03:53:38

标签: swift append uipickerview

这是我试图为一家小公司开发的应用程序的另一个问题。从本质上讲,我希望让人们更容易找到帐号。 PickerView中的第一列基本上是部门。第二个将是他/她将要完成的任务,第三个将是位置。我已经弄清楚如何直观地制作3列,但我无法弄清楚如何将它放入代码中。由此,我的意思是如何实际设置第三列的值/选择。此外,我在尝试将其与.append函数连接时遇到了一些问题,因此只有某些选项会在列中显示某些选项。追加功能不是必需的,但如果可能的话,最好使用它。

这是我编写的第一个应用程序,我“训练自己”,因此我的业余错误,如果有的话。任何帮助表示赞赏。

import UIKit

cllass Account {
var account: String
var jlCode: [String]
var location: [[String]]

init(account:String, jlCode:[String], location:[[String]]) {
    self.jlCode = jlCode
    self.account = account
    self.location = location
    }

}

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

@IBOutlet weak var pickerView: UIPickerView!
@IBOutlet weak var accountLbl: UILabel!
@IBOutlet weak var infoLbl: UILabel!
@IBOutlet weak var imageView: UIImageView!

var accounts = [Account]()

override func viewDidLoad() {

    pickerView.delegate = self
    pickerView.dataSource = self

    infoLbl.text = """
    test
    """

    //A. PARKS - Tasks for account number 12345678910

    accounts.append(Account(account: "12345678910", jlCode: ["task 1"], location: [["here"]]))

    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 3
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if component == 0 {
        return accounts.count
    } else if component == 1 {
        let selectedAccount = pickerView.selectedRow(inComponent: 0)
        return accounts[selectedAccount].jlCode.count
    } else if component == 2 {
        let selectedAccount = pickerView.selectedRow(inComponent: 0)
        let selectedjlCode = pickerView.selectedRow(inComponent: 1)
        let location = pickerView.selectedRow(inComponent: 2)
        return accounts[selectedAccount].jlCode[selectedjlCode].location.count
    }
    return 3
}


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if component == 0 {
        return accounts[row].account
    } else if component == 1 {
        let selectedAccount = pickerView.selectedRow(inComponent: 0)
        return accounts[selectedAccount].jlCode[row]
    } else if component == 2 {
        let selectedAccount = pickerView.selectedRow(inComponent: 0)
        let selectedjlCode = pickerView.selectedRow(inComponent: 1)
        let selectedLocation = pickerView.selectedRow(inComponent: 2)
        return accounts[selectedAccount].jlCode[selectedjlCode].location[selectedLocation]
    }
    return nil
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    pickerView.reloadComponent(1)

    let selectedAccount = pickerView.selectedRow(inComponent: 0)
    let selectedjlCode = pickerView.selectedRow(inComponent: 1)
    let account = accounts[selectedAccount].account
    let jlCode = accounts[selectedAccount].jlCode[selectedjlCode]

    accountLbl.text = "Account Number: \(account)\nJL Code: \(jlCode)"

}
}

1 个答案:

答案 0 :(得分:1)

看来你的titleForRow功能有点缺乏。您目前只提供组件0(帐户)和...... 帐户的任何内容。您需要更明确,并相应地提供文本。

为了帮助您,并让您更容易理解发生的事情,我建议您在课堂上创建这些常量吗?

private let accountsComponent = 0
private let tasksComponent = 1
private let locationsComponent = 2

然后你应该改变titleForRow函数来满足上述所有任务:

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if component == accountsComponent {
        return accounts[row].account
    } else if component == tasksComponent {
        let selectedAccount = pickerView.selectedRow(inComponent: accountsComponent)
        return accounts[selectedAccount].jlCode[row]
    } else if component == locationsComponent {
        // THIS IS WHAT IS MISSING
        // You need to return the location strings from this place.
    }
    return nil
}   

您需要从if component == locationsComponent部分...

返回相应的字符串

[EDIT2] 好的,既然你刚开始我会更加努力: 你并没有明确地掌握numberOfRowsInComponenttitleForRow函数的用途(?)

numberOfRows告诉组件每个组件(“列”)包含多少个值titleForRow是您返回应为每个组件中的每一行显示的实际文本字符串的位置。

因此,正如我在评论中提到的,创建一个Location结构:

struct Location {
    var identifier: Int
    var label: String
}

在控制器中,创建此结构的数组。

let locations: [Location] = [Location(identifier: 1, label: "Outdoors"),
                             Location(identifier: 2, label: "Indoor"),
                             Location(identifier: 3, label: "Narnia")]

然后你的numberOfRows应该依靠这个数组来返回location-component的适当行数:

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    // Only including the parts to return the location-stuff 
    } else if component == 2 {
        return locations.count
    }
    return 0 // This will never be reached as long as the numberOfComponents returns 3
}

和titleForRow:

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    // Only including the parts to return the location-stuff 
    } else if component == 2 {
        return locations[row].label
    }
    return nil
}