带有选择器(分段控件)子视图和选择手势的列表项 [英] List Item with Picker (segmented control) subview and selection gesture

查看:29
本文介绍了带有选择器(分段控件)子视图和选择手势的列表项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 List 和包含 Picker 视图(分段控制麦粒肿)的项目.我想分别处理选择和选择器状态.未选择列表项时应禁用选择器.

I have a List and items containing a Picker view (segmented control stye). I would like to handle selection and picker state separately. the picker should be disabled when list item is not selected.

问题是:

  • 第一次点击 - 选择列表项.(选择 = 真)
  • 点击选择器 - 设置选择 = false

在 UIKit、Button/SegmentControl/等上...抓住点击",不要进入 TableView 选择状态.

On UIKit, Button/SegmentControl/etc... catch the 'tap' and do not pass through to TableView selection state.

struct ListView: View {
    @State var selected = Set<Int>()
    let items = (1...10).map { ItemDataModel(id: $0) }
    
    var body: some View {
        List(items) { item in
            ListItemView(dataModel: item)
                .onTapGesture { if !(selected.remove(item.id) != .none) { selected.insert(item.id) }}
        }
    }
}

struct ListItemView: View {
    @ObservedObject var dataModel: ItemDataModel
    
    var body: some View {
        let pickerBinding = Binding<Int>(
            get: { dataModel.state?.rawValue ?? -1 },
            set: { dataModel.state = DataState(rawValue: $0) }
        )
        HStack {
            Text(dataModel.title)
            Spacer()
            Picker("sdf", selection: pickerBinding) {
                Text("State 1").tag(0)
                Text("State 2").tag(1)
                Text("State 3").tag(2)
            }.pickerStyle(SegmentedPickerStyle())
        }
    }
}


enum DataState: Int {
    case state1, state2, state3
}

class ItemDataModel: Hashable, Identifiable, ObservableObject {
    let id: Int
    let title: String
    @Published var state: DataState? = .state1
    
    init(id: Int) {
        self.id = id
        title = "item \(id)"
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
    }
    
    static func == (lhs: ItemDataModel, rhs: ItemDataModel) -> Bool {
        return lhs.id == rhs.id
    }
}

[请尽量忽略语法错误(如果存在)并专注于手势问题]

[Please try to ignore syntax errors (if exsist) and focus on the gesture issue]

推荐答案

一个可能的解决方案是仅在 Picker 未被选中时应用修饰符:

A possible solution is to apply modifiers only when the Picker is not selected:

struct ListView: View {
    @State var selected = Set<Int>()
    let items = (1 ... 10).map { ItemDataModel(id: $0) }

    var body: some View {
        List(items) { item in
            if selected.contains(item.id) {
                ListItemView(dataModel: item)
            } else {
                ListItemView(dataModel: item)
                    .disabled(true)
                    .onTapGesture {
                        if !(selected.remove(item.id) != .none) {
                            selected.insert(item.id)
                        }
                    }
            }
        }
    }
}

这篇关于带有选择器(分段控件)子视图和选择手势的列表项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆