SwiftUI 城市选择器 --多级联动

4 篇文章 0 订阅
1 篇文章 0 订阅

SwiftUI 城市选择器

效果图
在这里插入图片描述

//
/*!
 -------------------------------------------------------------------------------
   File name:       CityPicker.swift
   Author:            lanyuejing

   Description:    城市选择器

   History:
              2023/4/15: File created. at version v版本号

 -------------------------------------------------------------------------------
 */

import Foundation
import SwiftUI
import SwiftyJSON

struct CityPicker: View {
    // MARK: Internal

    var body: some View {
        let provinceName = addressItems[safe: selectProvinceIndex]?.name
        let city = addressItems[safe: selectProvinceIndex]?.childs[safe: selectCityIndex]?.name
        let area = addressItems[safe: selectProvinceIndex]?.childs[safe: selectCityIndex]?.childs[safe: selectAreaIndex]?.name
        VStack(spacing: 20) {
            HStack {
                Text("\(provinceName ?? "未选择")")
                Text("\(city ?? "")")
                Text("\(area ?? "")")
            }.foregroundColor(Color.black)
            GeometryReader { geometry in
                HStack(spacing: 0) {
                    Picker("省", selection: $selectProvinceIndex) {
                        ForEach(0..<addressItems.count, id: \.self) { index in
                            let name = addressItems[index].name
                            Text(name)
                        }
                    }
                    .onChange(of: selectProvinceIndex, perform: { _ in
                        changeSelectCity(selectCityIndex: 0)
                    })
                    .frame(width: geometry.size.width/3, alignment: .center)
                    .clipped()

                    Picker("市", selection: $selectCityIndex) {
                        let cities = addressItems[safe: selectProvinceIndex]?.childs
                        if let cities = cities {
                            ForEach(0..<cities.count, id: \.self) { index in
                                let name = cities[safe: index]?.name ?? ""
                                Text(name)
                            }
                        } else {
                            EmptyView()
                        }
                    }
                    .onChange(of: selectCityIndex, perform: { newValue in
                        changeSelectAreas(selectCityIndex: newValue)
                    })
                    .frame(width: geometry.size.width/3, alignment: .center)
                    .clipped()
                    Picker("区", selection: $selectAreaIndex) {
                        let selectedArea = self.addressItems[safe: selectProvinceIndex]?.childs[safe: selectCityIndex]?.childs
                        if let areas = selectedArea {
                            ForEach(0..<areas.count, id: \.self) { index in
                                let name = areas[safe: index]?.name ?? ""
                                Text(name)
                            }
                        } else {
                            EmptyView()
                        }
                    }
                    .frame(width: geometry.size.width/3, alignment: .center)
                    .clipped()
                }
            }
        }.onAppear(perform: { loadAddress() })
    }

    // MARK: Private

    @State private var addressItems: [Province] = []
    @State private var selectProvinceIndex = 0
    @State private var selectCityIndex = 0
    @State private var selectAreaIndex = 0

    private func loadAddress() {
        let bundle = Bundle.main
        let plistPath = bundle.path(forResource: "newaddress", ofType: "plist")
        let addressDic = NSDictionary(contentsOfFile: plistPath ?? "") ?? ["": ""]
        let jsonData = JSON(addressDic)
        let provincesItems = Address(json: jsonData).provinces
        addressItems = provincesItems
    }

    private func changeSelectAreas(selectCityIndex: Int) {
        selectAreaIndex = selectCityIndex
    }

    private func changeSelectCity(selectCityIndex: Int) {
        self.selectCityIndex = selectCityIndex
        selectAreaIndex = 0
    }
}

public extension Collection {
    subscript(safe index: Index) -> Element? {
        indices.contains(index) ? self[index] : nil
    }
}

struct CityPicker_Previews: PreviewProvider {
    static var previews: some View {
        CityPicker()
    }
}

折叠效果之城市选择器
在这里插入图片描述

//
/*!
 -------------------------------------------------------------------------------
   File name:       AddressView.swift
   Author:            langyuejing

   Description:    城市选择器
   History:
              2023/4/15: File created. at version v版本号

 -------------------------------------------------------------------------------
 */

import Foundation
import SwiftUI
import SwiftyJSON

struct AddressView: View {
    // MARK: Internal

    var body: some View {
        VStack {
            GeometryReader { geometry in
                List(addressItems, children: \.childs, selection: $selectionItem, rowContent: { item in
                    if item.provincecode.count > 0, item.citycode.count > 0 {
                        Text(item.name).foregroundColor(Color.black).onTapGesture {
                            selectionItem = item
                        }.frame(width: geometry.size.width - 40, alignment: .leading).padding(.leading, 80)
                    } else {
                        Text(item.name).foregroundColor(Color.black).onTapGesture {
                            selectionItem = item
                        }
                    }
                }).onAppear(perform: { loadAddress() })
            }
        }
    }

    // MARK: Private

    @State private var showAlert = false
    @State private var tapValue = "123"

    @State private var selectionItem: AreaModel?
    @State private var selectProvinceIndex = 0
    @State private var selectCityIndex = 0
    @State private var selectAreaIndex = 0
    @State private var addressItems: [AreaModel] = []
    @State private var flags: [Bool] = [false, false, false]
    @State private var items: [Any] = []

    private func loadAddress() {
        let bundle = Bundle.main
        let plistPath = bundle.path(forResource: "newaddress", ofType: "plist")
        let addressDic = NSDictionary(contentsOfFile: plistPath ?? "") ?? ["": ""]
        let jsonData = JSON(addressDic)
        let provincesItems = AreaList(json: jsonData).areaList
        addressItems = provincesItems
    }
}

struct AddressView_Previews: PreviewProvider {
    static var previews: some View {
        AddressView()
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]和\[2\]中的代码是一个示例,展示了一个多级联动的u-picker组件。该组件用于选择村组的数据,根据传入的pid展示不同的村组数据。点击输入框后,会弹出u-picker组件,用户可以选择村组。引用\[2\]中的代码展示了获取村组信息和实现村组多列联动的事件处理函数。其中,getGroup函数用于获取村组数据,根据传入的pid不同,将数据存储在options数组中的不同位置。changeHandler函数用于处理用户选择村组时的事件,当第一列的值发生变化时,会根据选择的值获取对应的第二列的选项,并更新u-picker组件的选项。这样就实现了多级联动效果。 所以,u-view picker多级联动是通过u-picker组件和相应的事件处理函数来实现的。用户可以根据自己的需求,配置不同的数据和事件处理逻辑,实现多级联动效果。 #### 引用[.reference_title] - *1* *2* [uniapp实现村组数据多级联动](https://blog.csdn.net/weixin_46319117/article/details/128120496)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [uview 之 三级联动](https://blog.csdn.net/qq_40796623/article/details/125478188)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值