17 Replies
      Latest reply on Mar 26, 2020 5:56 PM by 724QD58FHA
      anorskog Level 1 Level 1 (0 points)

        Can one get multiple buttons to work when included in a List row?

         

        This problem can be seen in the completed version of the Apple tutorial.  There, the HikeDetail or HikeView each work when previewed by itself - one can select different graphs by the Elevation, Heart Rate, and Pace buttons.  However, this view does not work properly when it is included in the ProfileSummary List().  When tapping on one of the buttons, the view collapses.  This is because all buttons are activated, rather than just the one tapped.

         

        It seems that List() is deciding that if it sees a button in the row, it will change multiple behaviors:

          1) The button is no longer tinted - if one uses a simple button, it is tinted outside of a List.  (Note: The tutorial is playing with colors to show blue/gray - even in the List view).

          2) The button no longer flashes when pressed/tapped.

          3) A tap in the row activates the actions of all buttons included in that row.

         

        I can understand that this might be the desired behavior to make the simplest row - when only one button.  But it is frustrating when one can no longer depend on the look or actions that one has built up at lower levels of the code, just because one now includes it in a List table.

         

        One partial workaround is to not use Button(), but rather add a tap or gesture to the view one has built up.  But then one doesn’t get the helpful flash animation available in a button.

         

        Looking particularly for a way to get items 2 and 3 above to work together.  Can work around item 1 like was done in the tutorial - but might be nice if this worked, too.

        • Re: Swiftui list row with multiple buttons?
          anorskog Level 1 Level 1 (0 points)

          Note: Just updated to XCode 11.0 beta 3 and a new copy of the Apple Tutorial.  The Tutorial still shows the problem.

            • Re: Swiftui list row with multiple buttons?
              rezahler Level 1 Level 1 (0 points)

              When I put multiple buttons in the same List or Form, initially all the buttons provide only the action of the first button.  Thereafter, additional taps produce no action.  I am doing this in the context of “help” buttons that open an alert sheet with guidance for using a particular part of the app.

            • Re: Swiftui list row with multiple buttons?
              SilentJohn Level 1 Level 1 (0 points)

              Same problem with me in Xcode 11 beta 3. I tried to nest three buttons in a stack ,then put the stack in a row of a list. As the code shows:

              struct TestCellTap : View {
                  var body: some View {
                      List {
                          SomeButtons()
                      }
                  }
              }
              
              struct SomeButtons: View {
                  var body: some View {
                      HStack {
                          Button(action: {
                              print("First button is tapped")
                          }) {
                              Text("First")
                          }
                          Spacer()
                          Button(action: {
                              print("Second button is tapped")
                          }) {
                              Text("Second")
                          }
                          Spacer()
                          Button(action: {
                              print("Third button is tapped")
                          }) {
                              Text("Third")
                          }
                      }
                  }
              }
              

               

              When I tried to tap one of the three buttons, it seems that the row got the tap instead of any button it nests, and all the actions of the three buttons were triggered. And I got same result when tapping at any point out of the three buttons.

                • Re: Swiftui list row with multiple buttons?
                  724QD58FHA Level 1 Level 1 (0 points)

                  I'm having the same problem with two Buttons inside an HStack. This condition was noticed after the update to macOS Catalina, Version 10.15.4. Did not notice this problem before the update. I did try the ".buttonStyle(DefaultButtonStyle()" solution given in a Post below, but it did not solve my problem.

                    • Re: Swiftui list row with multiple buttons?
                      724QD58FHA Level 1 Level 1 (0 points)

                      After a little more investigation it looks like a .onTapGesture Instance Method might be a better practice than Button Generic Structure.

                       

                      import SwiftUI
                      
                      struct ContentView: View {
                          var body: some View {
                              VStack {
                                  HStack {
                                      Text("Left Button")
                                          .onTapGesture {
                                              print("Left Button Tapped")
                                      }
                                      Spacer()
                                      Text("Right Button")
                                          .onTapGesture {
                                              print("Right Button Tapped")
                                      }
                                  }
                              }
                          }
                      }

                       

                      For a few different reasons this looks like it could be more reliable than using Buttons?

                  • Re: Swiftui list row with multiple buttons?
                    anorskog Level 1 Level 1 (0 points)

                    Upgraded to beta 4. The tutorial is still broken and can't deal with multiple buttons on the "Recent Hikes" row.  And as shown by the simpler example above by SilentJohn.

                    • Re: Swiftui list row with multiple buttons?
                      anorskog Level 1 Level 1 (0 points)

                      Upgraded to beta 5.  The Apple tutorial is still broken - "Recent Hikes" row still doesn't behave as it should.  Basically, still indicating that you still cannot have multiple buttons on a List row.  Even if the standard was to only allow/work with one button, I was hoping that Apple would provide a way to turn off the "standard" behavior so that the behavior that was built up for that item (as seen earlier in the tutorial) would work when it was included in a List.

                      • Re: Swiftui list row with multiple buttons?
                        anorskog Level 1 Level 1 (0 points)

                        Upgraded to beta 6.  Problem described in this post and the Apple tutorial are still broken as described above.

                        • Re: Swiftui list row with multiple buttons?
                          anorskog Level 1 Level 1 (0 points)

                          Broken record.  Apple tutorial still not working with Beta 7.

                          • Re: Swiftui list row with multiple buttons?
                            Geoffrain Level 1 Level 1 (0 points)

                            Try leaving the action blank and use .onTapGesture instead:

                             

                                                Button(action: {}, label: {Image(systemName: "chevron.right.circle")}).onTapGesture {
                                                    <#code#>
                                                }
                            
                              • Re: Swiftui list row with multiple buttons?
                                anorskog Level 1 Level 1 (0 points)

                                Thanks. One can sort of get things to work if one moves the action for ALL the buttons to their respective onTapGesture{} call, and not just the chevron button.

                                 

                                But then one realizes that one doesn't need (shouldn't use?) buttons at all!  Removing the action for a button, then one should just use the Image() or Text() "views" with the onTapGesture{} call.

                                 

                                So, basically, if you are going to eventually use List(), don't use Button() - especially if you might have multiple in a cell. ??? Guess I'm still hoping Apple will eventually allow multiple buttons in a cell.

                              • Re: Swiftui list row with multiple buttons?
                                rspoon3 Level 1 Level 1 (0 points)

                                I just spent hours trying to figure out why my buttons were not working and tracked down this being the reason. If you use a scrollview instead they work. However scrollview currently has its own problems when being used with a navigation link.

                                • Re: Swiftui list row with multiple buttons?
                                  anorskog Level 1 Level 1 (0 points)

                                  Apple Tutorial still broken after upgrading to Xcode GM_Seed.  Still has no change or workaround for dealing with multiple buttons in a List row.

                                  • Re: Swiftui list row with multiple buttons?
                                    ctarmor Level 1 Level 1 (0 points)

                                    Here one solution using a modifier and ignoring the button tap. ButtonRefresh below is in a list. 

                                     

                                    Visually the containing list item "clicks", but only the referesh button is actioned.

                                     

                                    Hope it helps

                                     

                                     

                                    struct YastIconButtonStyle: ViewModifier {

                                        func body(content: Content) -> some View {

                                            content

                                                .background(Color.yellow)

                                                .mask(Circle())

                                        }

                                    }

                                     

                                     

                                     

                                    extension View {

                                        func ApplyImageIconsButtonStyle(command: @escaping () -> Void) -> some View {

                                            self

                                                .modifier(YastIconButtonStyle())

                                                .onTapGesture {

                                                    command()

                                            }

                                        }

                                    }

                                     

                                     

                                    struct ButtonRefresh: View {

                                        var body: some View {

                                            Button(action: CmdLoadPortolioOnline) {

                                                Image("Refresh")

                                                    .ApplyImageIconsButtonStyle(command: CmdLoadPortolioOnline)

                                            }.onTapGesture {

                                                // Do nothing

                                            }

                                        }

                                    }

                                    • Re: Swiftui list row with multiple buttons?
                                      AntonL Level 1 Level 1 (0 points)

                                      Setting the ButtonStyle seems to do the trick

                                      struct Test: View {
                                        var body: some View {
                                          NavigationView {
                                            List {
                                              Button(action: { print("Prefix")}) {
                                                Text("Prefix 1")
                                              }
                                              Button(action: { print("Prefix")}) {
                                                Text("Prefix 2")
                                              }
                                              .buttonStyle(DefaultButtonStyle())
                                              ForEach([
                                                "Line 1",
                                                "Line 2",
                                              ], id: \.self) {
                                                item in
                                                HStack {
                                                  Text("\(item)")
                                                  Spacer()
                                                  Button(action: { print("\(item) 1")}) {
                                                    Text("Button 1")
                                                  }
                                                  Button(action: { print("\(item) 2")}) {
                                                    Text("Button 2")
                                                  }
                                                }
                                              }
                                              .onDelete { _ in }
                                              .buttonStyle(BorderlessButtonStyle())
                                            }
                                            .navigationBarItems(trailing: EditButton())
                                          }
                                          .accentColor(.red)
                                        }
                                      }