Links, Lists and Buttons
I have been working on one of my apps, it's completely in SwiftUI. During this I was running into some issues with some more complex views and learned about some modifiers. That I just wanted to share here, and maybe I will be needing these links in the future.
First was an issue where I needed some buttons in a List. When placing some Buttons inside a row in a SwiftUI List, the Buttons all get tapped when clicking on the row, or any of the Buttons. That was not wanted in my case. This great blog post by lars explains the issue and has a great fix. (I really did not like the idea of using .onTapGesture{}) All that was missing for me was adding the .buttonStyle(.borderless). Now my Buttons work again!
Next I noticed that I want to add a long press gesture to a Button. My idea was that you could press the Button, and undo it's action by long pressing it. Is that a weird UX? Probably, but it seemed like a good idea. In my app, teachers can write down if a student is late to class, they can do so in 5 min intervalls. If they press the Button, 5 minutes will be added to the students record. When long pressing that button, 5 min can be removed again. (Yes, the students are the rows in my list.) I was searching the internet with a term like 'Button long press gesture swiftui'. This lead me down some results that weren't really great for what I wanted to do. Then I remembered that the actual term used is a Menu. This lead me to This great article by Paul Hudson from Hacking with Swift. I did not know that there was a Menu with a primaryAction! That was a nice new thing for me. (yes, iOS 15 is some time ago.)
Then, I wanted to place a NavigationLink in that row. (Yes, it's a List with rows that have both quick action Buttons and a navigation to more detailed actions.) That was a mistake. I ended up going with a .sheet() modifier and a Button. That might also not be the best solution, but I do not want to place a NavigationStack, as that would mean a bigger refactor, and I am not open to that right now. But! I learned about a fun modifier. One problem was that my NavigationLink would show up as the shape and style I programmed when not in a NavigationView/NavigationStack (a circle with an arrow), but would try to fill the entire width of the row and adding an arrow at the right side when in a navigation context. I know that that is how links are displayed in Lists. But I did not want the arrow, as my Label was already showing an arrow. Also, I was using a .clipShape(.circle). That means the view got clipped to the middle part, which in my case was an empty space between my circle-with-arrow-shape and the NavigationLinks arrow. This can be resolved by adding .navigationLinkIndicatorVisibility(.hidden) to the NavigationLink! How fun! It's available iOS in 17.0+.
Oh and when I am already at List. This is a great article by Karin Prater at SwiftyPlace about how to customize a List to your liking. I always find myself going back to this article! It's so great that every possible modifier and combination is used and illustrated with images.