gutters on sides of List in WatchOS - swiftui

I'm dipping my toe into SwiftUI and WatchOS for the first time. I'm making good progress, but I can't figure out how to get rid of the black "gutters" on either side of my Image controls. I've tried setting all the backgrounds to white, but the gutter persists.
What property on which view do I need to set to change the color of the gutters to match the background?
SwiftUI
struct ContentView: View {
var body: some View {
List {
Image("cat-1").resizable().scaledToFill().background(Color.white)
Image("cat-2").resizable().scaledToFit().padding(5).background(Color.white)
Image("cat-3").resizable().scaledToFit().padding(.top, 5).background(Color.white)
}.background(Color.white).listStyle(CarouselListStyle())
.background(Color.white)
}
}

Try adding a
.listRowPlatterColor(.clear)
put it inside the list like this...
struct ContentView: View {
var body: some View {
List {
Image("cat-1")
.resizable()
.scaledToFit()
.listRowPlatterColor(.clear)
Image("cat-2").resizable().scaledToFit().padding(5).background(Color.white)
Image("cat-1")
.resizable()
.scaledToFit()
.padding(.top, 5)
.background(Color.white)
}
.listStyle(CarouselListStyle())
}
}
I put it in the first item and left it off of the second and third so that you could see the difference. This other question can provide some more details:
How to style rows in SwiftUI List on WatchOS? .
You should then be able to style it however you like.

Related

Why is the SwiftUI TextEditor glitching upon font size changes?

I'm trying to create a TextEditor view where the user can customize the font size, but whenever I adjust the font size using a Slider and go back to typing in the TextEditor, the TextEditor starts glitching: the scroll position jumps up and down, the cursor ends up in the wrong position, and the text flickers.
Here's a reduced test case:
struct ContentView: View {
#State var text: String
#State var textSize: CGFloat
var body: some View {
VStack {
Slider(value: $textSize, in: 20.0...80.0)
TextEditor(text: $text)
.font(.system(size: textSize, weight: .semibold))
}
.padding()
}
}
Just type some text, adjust the font size, type more text. You might need to repeat that a few times, but it eventually starts glitching.
My hypothesis is that part of the UI isn't being updated on the main thread, but maybe that's just me coming from UIKit and not fully understanding SwiftUI yet.
Using Xcode 14.2 and iOS 16.2.

How to get rid of empty space when trying to insert a view flush to navigation bar, while simultaneously assigning navigation view a background color

To my knowledge, the only way to assign a navigation bar a background color that is separate from the rest of the screen, you set the background color to whatever object you have flush with the navigation view. (In this case, its a divider with the background set to red)
My intention is to then place a view flush to the divider in an attempt to create some sort of "subtitle view". The problem is, as you can see, there is a space between my Stack and my Divider... I'm not sure what is causing this space and I am not sure how to get rid of it.
My first thought was, perhaps there is some safe area being adhered to... That said, I tried ignoring that, but that didn't work.
struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
Divider()
.background(.red)
.navigationTitle("Main Title")
// There is a space here
ZStack {
Rectangle().frame(height: 35)
Text("Subtitle View")
.foregroundColor(.white)
}.edgesIgnoringSafeArea([.top, .bottom])
Spacer()
}.background(.blue)
}
}
}

SwiftUI: present popover on iPhone?

I am looking at the Apple Reminders app and want to build the same pop over like view on iPhone. This the screen I am referring to:
So, I can present a popover like UI on an iPad using the popover modifier.
struct ContentView: View {
// 1.
#State var isPopoverPresented = false
var body: some View {
// 2.
Button(action: {
self.isPopoverPresented = true
}) {
Text("Some content")
}
// 3.
.popover(isPresented: $isPopoverPresented) {
Text("Popover is Presented")
.font(.largeTitle)
.frame(width: 200, height: 300)
}
}
}
However when that code runs on an iPhone, the popover turns in a fullscreen modal coming up from the bottom.
I want to know if there is a native way to build a screen like the one shown in the Reminders app or, is that screen a custom View with custom layout logic on an iPhone?
You're looking for a Menu (UIMenu in UIKit). Note that it's iOS 14+ only.

SwiftUI Buttons in a ScrollView is not tappable sometimes

I have a horizontal ScrollView on top of a MapView.
The ScorllView is a collection of Buttons. It is weird that the buttons in the ScrollView are sometime tapable and sometimes not. First tap always works but after that I have to scroll a bit, tap around different areas in the button, make some secret prayers and then it works!
I tried disabling/removing all other components in the view, but still unable to figure out the root cause.
Has anyone experience this ?
I stuck with a same issue with horizontal ScrollView on top and List. While debugging I added empty .onTapGesture to ScrollView and it somehow fix my issue.
VStack(spacing: 0) {
ScrollView(.horizontal) {
HStack {
Button("one") {}
Button("two") {}
Button("three") {}
}
}
.onTapGesture { // <---- fix
}
List {
}
}
I also faced the same issue for Horizontal Scroll view in Swiftui dark theme "CameraTimerItem" buttons not clickable (Problem with dark theme only). Then I put a onTapGesture without any action. It's starts to work normally. I think it's a error of SwiftUI.
VStack (alignment:.center){
ScrollView(.horizontal, showsIndicators: false) {
HStack{
ForEach(timeSlots,id: \.self) { item in
CameraTimerItem(cellTitle: item)
}
}
.frame(width: AppUtils.width, alignment: .center)
}
.onTapGesture {
// <---- This is the solution
}
}
To anyone else having this issue, instead of adding an empty .onTapGesture view modifier, check that any HStacks in the ScrollView hierarchy have a .contentShape(Rectangle()) modifier. By default, HStacks don't accept taps in between their child views, and depending on your child view's layout this can cause taps to be missed even when it looks like they should be landing. .contentShape(Rectangle()) makes the entire frame of the HStack tappable.

How to do Apple Music-like navigation in SwiftUI? Custom List and NavigationView has highlight not going away

This is my example that I am trying to get to work:
struct ContentView: View {
let links = ["Item 1", "Item 2", "Item 3", "Item 4"]
var body: some View {
NavigationView {
ScrollView {
Text("My Title")
List(links, id: \.self) {
link in
NavigationLink(destination: TestView()) {
Text(link)
.padding(.vertical, 4)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
.frame(height: 178)
Text("Some more content here")
}
}
}
}
Note: TestView is just some view with the text hello world on it.
I am trying to copy Apple Music's style of navigation. I tried putting a Button in the NavigationLink but tapping it on the text wouldn't change views, and I couldn't find a way to reliably change the color of the row when tapped, at the same time. Also in some approach, I managed to make it work, but the way the colors animate is different, i.e. it fades from A to B, over ~100ms whereas what I'm trying to achieve is to animate between the states instantly (like in Apple Music).
My current approach is using a List, putting NavigationLinks inside it and then cutting off the whole view by giving it a height. This way I can put it alongside other content.
It's working fine for now, but whenever I click on an row and go back, the row is still highlighted, when it shouldn't. Is there a way to make it so that it deselects when going back to the screen somehow?
I think this bug is being caused by the List being inside a ScrollView, since when I removed ScrollView, the list worked properly, and there wasn't this highlight bug. But I need to be able to put my content with the list, and I don't intend to have a list take up the whole screen.
Is there any way to fix this bug with this approach? I'm also willing for other ways to achieve the same result without using List.
Trying to use ForEach instead ofList?
With a view for row (CustomRow) where you can pass link item and set custom dividing line, background etc ...
ForEach(links, id: \.self) { link in
NavigationLink(destination: TestView()) {
CustomRow(item: link)
}
}
.frame(height: 178)