UIPickerViewと辞書型で筋トレの内容をlabelに表示させる


せっかくなのでメモ。Swift5 Xcode12.2
UIPickerViewで部位と種目をそれぞれ選択します。
辞書型を使い、選択した部位によって種目のpickerが変わります。

辞書の宣言

    let menuDataList: [String: [String]] = [
        "脚": ["スクワット","レッグプレス","レッグエクステンション","レッグカール"],
        "背中": ["デッドリフト","ベントオーバーローイング","チンニング","ラットプルダウン"],
        "胸": ["バーベルベンチプレス","ダンベルベンチプレス","インクラインダンベルベンチプレス","ペックフライ"],
        "肩": ["サイドレイズ","フロントレイズ","リアレイズ","ショルダープレス"],
        "三頭": ["ナローベンチプレス","トライセプスエクステンション","ケーブルプレスダウン","ダンベルキックバック"],
        "二頭": ["ダンベルカール","インクラインダンベルカール","プリチャーカール","ハンマーカール"],
        "腹": ["クランチ","インクラインクランチ","レッグレイズ"]
    ]
    var partsDataList: [String] = [
        "脚","背中","胸","肩","三頭","二頭","腹"
    ]
    var selectedParts = ""

2つのpickerにタグを振り分ける

override func viewDidLoad() {
        super.viewDidLoad()
        partsPickerView.delegate = self
        partsPickerView.dataSource = self
        menuPickerView.delegate = self
        menuPickerView.dataSource = self
        partsPickerView.tag = 1
        menuPickerView.tag = 2
        selectedParts = partsDataList[0]
    }

PickerViewの個数を返す

    func pickerView(_ pickerView: UIPickerView,
                    numberOfRowsInComponent component: Int) -> Int {
        if pickerView.tag == 1{
            return partsDataList.count
        } else if pickerView.tag == 2{
            //menuDataListのオプショナル型にアンラップされたselectedPartsの要素数が空だったら0を返す
            return menuDataList[selectedParts]?.count ?? 0
        } else {
            return 0
        }
    }

表示内容

    func pickerView(_ picker: UIPickerView,
                    titleForRow row: Int,
                    forComponent component: Int) -> String? {
        if picker.tag == 1 {
            return partsDataList[row]
        } else if picker.tag == 2 {
            //menuDataListのオプショナル型にアンラップされたselectedPartsのrow番目が空だったら空文字列を返す
            return menuDataList[selectedParts]?[row] ?? ""
        } else {
            return ""
        }
    }

UIPickerViewのRowが選択された時の挙動

    func pickerView(_ pickerView: UIPickerView,
                    didSelectRow row: Int,
                    inComponent component: Int) {
        if pickerView.tag == 1 {
            partsLabel.text = partsDataList[row]
            selectedParts = partsDataList[row]
            menuPickerView.reloadAllComponents()
        } else if pickerView.tag == 2 {
            //menuDataListのオプショナル型にアンラップされたselectedPartsのrow番目が空だったら空文字列をmenuLabelのtextへ返す
            menuLabel.text = menuDataList[selectedParts]?[row] ?? ""
        } else {
            return
        }
    }