I'm almost there, but again, no.
I get the source of truth to work on one level, but almost without exception I have created something that only consists of one level.
I have a github example to make it easy to reproduce the scenario. I hope it´s me and not a feature of SwiftUI :)
Post
Replies
Boosts
Views
Activity
Returning from a sheet nither a click or a tap gesture triggers on a component in a list, until you perform a drag gesture.
The best is to see it, so to reproduce the situation I have created a little test. copy and play
import SwiftUI
enum TriggerType: String, CaseIterable {
case button, tapGesture
}
enum ABC: String, CaseIterable {
case A,B,C
}
struct ContentView: View {
@State private var myLetters = [ABC]()
@State private var triggerType = TriggerType.button
var body: some View {
List {
// TriggerType
Picker(selection: $triggerType, label: Text("no")) {
ForEach(TriggerType.allCases, id: \.self) { type in
Text(type.rawValue)
}
}
.pickerStyle(SegmentedPickerStyle())
// select letter
LetterPicker(triggerType: $triggerType ,selected: $myLetters)
.disabled(myLetters.count = 3)
// view all selected letters
ForEach(myLetters, id: \.self) { letter in
MyButton(triggerType: $triggerType, label: letter.rawValue, symbol: "minus.circle.fill", symbolColor: .red) {
if let index = myLetters.firstIndex(of: letter) {
myLetters.remove(at: index)
}
}
}
// Information
Text(Info.text(triggerType: triggerType))
.padding(EdgeInsets(top: 20, leading: 20, bottom: 50, trailing: 20))
.multilineTextAlignment(.leading)
.font(.footnote)
}
}
}
struct LetterPicker: View {
@Binding var triggerType:TriggerType
@Binding var selected:[ABC]
@State private var showSheet = false
var body: some View {
MyButton(triggerType: $triggerType, label: "add a letter", symbol: "plus.circle.fill") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet, onDismiss:{},
content: { MySheet(triggerType: $triggerType, selected: $selected) })
}
}
struct MySheet:View {
@Binding var triggerType:TriggerType
@Binding var selected:[ABC]
@Environment(\.presentationMode) var presentationMode
var body: some View{
List{
ForEach(ABC.allCases, id: \.self) { letter in
if !selected.contains(letter){
MyButton(triggerType: $triggerType, label: letter.rawValue, symbol: nil) {
self.presentationMode.wrappedValue.dismiss()
selected.append(letter)
}
}
}
// Info
let info = "\(triggerType == .button ? "Click" : "Tap") on a letter"
HStack(alignment: .center, spacing: 0, content: {
Spacer()
Text(info)
.padding(EdgeInsets(top: 50, leading: 20, bottom: 50, trailing: 20))
Spacer()
})
}
}
}
struct MyButton: View {
@Environment(\.isEnabled) var isEnabled
@Binding var triggerType:TriggerType
var label: String
var symbol: String?
var symbolColor: Color = .blue
var action: () - Void
var body: some View{
HStack(alignment: .center, spacing: 10, content: {
Text("trigger: \(triggerType.rawValue)")
Spacer()
if let symbol = symbol {
if triggerType == .button {
Text(label)
Button(action: { action() }, label: {
Image(systemName: symbol)
.foregroundColor(isEnabled ? symbolColor : .gray)
})
.buttonStyle(BorderlessButtonStyle())
} else {
Text(label)
Image(systemName: symbol)
.foregroundColor(isEnabled ? symbolColor : .gray)
.onTapGesture {
action()
}
}
} else {
if triggerType == .button {
Button(action: { action() }, label: {
Text(label)
})
.buttonStyle(BorderlessButtonStyle())
} else {
Text(label)
.onTapGesture {
action()
}
.buttonStyle(BorderlessButtonStyle())
}
}
})
}
}
struct Info {
static func text(triggerType: TriggerType) - String {
// Info
return """
This is a test to check that a button action or tap gesture triggers
\(triggerType == .button ? "Click" : "Tap") on the plus image to add a letter
After adding a letter or two, do not touch the view before step 2 remove a letter by \(triggerType == .button ? "clicking" : "tapping") the minus image
if that removes the letter, Voila! everything is good :). The End
but!
If nothing happends, \(triggerType == .button ? "clicking" : "tapping") dose not remove the letter. Tap and hold anywhere on the screen, then drag down.
Go back to step 2.
If now after the draggesture it is possible to remove the letter, well then you expirienced exactly what I did - and that does not work well for me.
Is it me, a feature or is it a bug?
"""
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
tested in:
Xcode 12.5 beta 3, iOS 14.1 and 14.5
Xcode 12.4, iOS 14.1
Is it me, a feature or is it a bug?
Thanks!