SwiftUI轻击手势识别器只会在状态改变后调用一次

时间:2020-02-03 22:31:02

标签: swift swiftui gesture

我正在构建一个供Form使用的自定义视图(多轮选择器)。为了使Form保持紧凑,我只想在关联的行被点击时显示选择器。这应该很简单,但是我得到了一些意外的行为。

如果与轻击手势识别器关联的闭包不影响视图状态(例如,通过执行简单的打印语句),则所有轻击都将按预期注册。当我尝试通过在闭包中切换布尔值来更新视图状态时,轻击手势仅执行一次(显示选择器)。进一步的抽头不会影响进一步的状态更改。在层次结构中的所有视图上添加边框并未显示手势识别器的位置或尺寸有任何变化。

这应该是非常简单的实现,但是我浪费了很多时间来调试我的代码。当我发现自己做错了什么时,我无疑会踢自己,但与此同时,将不胜感激。该代码有点混乱,因为它目前只是概念证明。

//
//  MultiWheelPickerView.swift
//  AthenaVS
//
//  Created by Adrian Ward on 02/02/2020.
//  Copyright © 2020 AwardVetSciences. All rights reserved.
//

import SwiftUI

struct MultiWheelPickerView: View {
    @State private var isWheelVisible = false
    @State var selection = ["", ""]
    private var prompt: String {
        let currentValue = selection.reduce("", +)
        return currentValue.count == 0 ? "Not set" : currentValue
    }
    private var title: String = "title".uppercased()

    var body: some View {
        VStack(alignment: .center) {
            VStack(alignment: .leading) {
                HStack {
                    Text("\(self.title)")
                        .font(.caption)
                        .bold()
                    Spacer()
                    Text("\(prompt)")
                        .foregroundColor(Color.gray)
                }
                    .contentShape(Rectangle()) // ensures entire HStack is tapable
                    .onTapGesture {
                        self.isWheelVisible = !self.isWheelVisible
                        print("Tapped")
                }

                if isWheelVisible {
                    GeometryReader { geometry in
                        HStack {
                            ZStack {
                                Text("One")
                                Picker(selection: self.$selection[0], label: Text("one")) {
                                    ForEach(0..<10) { row in
                                        Text("\(row)")
                                            .tag(String(row))
                                    }
                                }
                                    .labelsHidden()  // label is misplaced otherwise
                                    .pickerStyle(WheelPickerStyle())
                                    .fixedSize(horizontal: true, vertical: true)
                                    .frame(width: geometry.size.width / 2,
                                           alignment: .trailing)
                                    .clipped() // to enusre touch zone matches the text position
                            }

                            ZStack {
                                Text("Two")
                                Picker(selection: self.$selection[1], label: Text("two")) {
                                    ForEach(10..<100) { row in
                                        Text("\(row)")
                                            .tag(String(row))
                                    }
                                }
                                    .labelsHidden() // label is misplaced otherwise
                                    .pickerStyle(WheelPickerStyle())
                                    .fixedSize(horizontal: true, vertical: true)
                                    .frame(width: geometry.size.width / 2, alignment: .trailing)
                                    .clipped() // to enusre touch zone matches the text position
                            }

                        }
                    }
                    .frame(height:100)
                        .clipped() // ensures that wheel isn't superimposed on next row
                }
            }

        }
    }
}

struct MultiPickerView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            Form {
                MultiWheelPickerView().previewDisplayName("As Form child")
            }
            MultiWheelPickerView().previewDisplayName("As View child")
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您GeometryReader正在拦截抽头,当拾取器是可见的。

您无法通过在其中添加<div id="bike_search_form"></div> <script src="#where should the script be?"></script> <script> var bike_search_form = new bike_search_form(''); bike_search_form.post_url = 'https://.myrailsapp.com'; bike_search_form.create(); </script> 来对其进行测试。

在将GeometryReader的框架高度设置为100之前,尝试添加(function() { var jQuery; if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') { var script_tag = document.createElement('script'); script_tag.setAttribute("type","text/javascript"); script_tag.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"); if (script_tag.readyState) { script_tag.onreadystatechange = function () { // For old versions of IE if (this.readyState == 'complete' || this.readyState == 'loaded') { scriptLoadHandler(); } }; } else { script_tag.onload = scriptLoadHandler; } (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag); } else { jQuery = window.jQuery; main(); } function scriptLoadHandler() { jQuery = window.jQuery.noConflict(true); main(); } function main() { jQuery(document).ready(function($) { var css_link = $("", { rel: "stylesheet", type: "text/css", href: "<%= URI.join(root_url, path_to_stylesheet("widget.css")).to_s %>" }); css_link.appendTo('head'); #Something to generate the form? }); } })(); 修饰符。这为我解决了这个问题。