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

Creating 3 columns in UIPickerView, also using append function

这是我正在尝试为一家小公司开发的应用程序的另一个问题。本质上,我想让人们更容易找到帐号。 PickerView 中的第一列本质上是部门。第二个是 he/she 将要执行的任务,第三个是位置。我已经想出如何在视觉上制作 3 列,但我不知道如何将它放入代码中。我的意思是如何为第三列实际设置 values/selections 。此外,我在尝试将它与 .append 函数连接时遇到了一些问题,以便在列中的某些选择中仅显示某些选项。 append 函数不是必需的,但如果可能的话使用它会很好。

这是我编写的第一个应用程序,我 "trained myself" 因此我的业余错误(如果有的话)。任何帮助表示赞赏。

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

}
}

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

为了帮助您前进,并让您更容易理解正在发生的事情,我建议您在 class?

的顶部创建这些常量
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
}   

您需要 return 来自 if component == locationsComponent 部分的适当字符串...

[编辑2] 好的,因为你才刚刚起步,我会加倍努力: 您是否已经准确掌握 numberOfRowsInComponenttitleForRow 函数的用途并不明显(?)

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

所以,正如我在评论中提到的,创建一个 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 应该依靠这个数组 return 位置组件的适当行数:

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
}