Remove default padding from List in SwiftUI - swift

When using ScrollView the views inside it are spread across the whole screen width by default, but when using List, there is a padding on the sides. Is there a way to get rid of this padding?

To achieve this you need to use ForEach inside List combined with .listRowInsets as in example below
struct Demo: View {
var colors: [Color] = [.red, .blue, .yellow]
var body: some View {
List {
ForEach(colors, id: \.self) { color in
color
}.listRowInsets(EdgeInsets())
}
// Update: Different iOS versions have different
// default List styles, so set explicit one if needed
.listStyle(PlainListStyle())
}
}

For iOS 15.0+, you may try listStyle modifier and set it as plain.
var body: some View {
List {
// some rows
}
.listStyle(.plain)
}

Related

SwiftUI Navigate up down not working in Grid

Here is my simple tvOS 16.0 app with the following code:
import SwiftUI
struct ContentView: View {
var sixColumnGrid: [GridItem] = Array(repeating: .init(.flexible()), count: 6)
let colors: [Color] = [.red, .green, .blue, .yellow, .cyan, .pink, .gray, .indigo, .brown]
var body: some View {
NavigationStack {
LazyVGrid(columns: sixColumnGrid) {
ForEach(colors, id: \.self) { color in
NavigationLink {
//MyView()
} label: {
Text(color.description.capitalized)
.padding()
.background(color)
}
.padding(20)
.buttonStyle(.card)
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The code is pretty simple where I have a LazyVGrid with six column. The grid is populated with 9 different colors. Each item of the grid is a NavigationLink
This is how it renders:
The issue I am facing is that one can navigate with up and down keys between two rows there only if there is any item directly below or above the source item from where we are pressing the up/down key.
For instance, in the above code example, if we press up key when we are on Brown color it takes us to Blue color, and if we press down key when we are on Blue color, we can navigate to Brown Color.
But the issue is that when you are on Yellow color, you can't go down to the bottom row via Down key, you need to go left first, towards the Blue color and then you can go down to the second row via Down key.
Can you share how we can make navigation to go up/down even if the element is not directly above or down below that same item in the grid.
My goal is to have multiple grids like that in my view but should be able to go up and down between those grids even if the item is not directly the above item from where we are pressing up/down keys.
Is there any limitation with NavigationStack/LazyVGrid/NavigationLink that one can navigate with up/down keys only if any item is directly present in down/up direction of that specific item?
How can we navigate to different sections of the pages via up/down keys if there is such limitation? It is not practical to have all the items aligned vertically on a page to make them navigate through up and down keys.

How to reduce height of a View in a List in SwiftUI

Is it possible to reduce the height of a row in a SwiftUI List? I can't seem to get it to go smaller than the default height.
I tried adding .listRowInsets(EdgeInsets()) on ForEach but it just changes the trailing and leading padding.
In UIKit, I could just use the tableView(_:heightForRowAt:) to adjust the height to the desired size.
struct ContentView: View {
var body: some View {
List {
ForEach(1...10, id: \.self) { i in
Text("\(i)")
}
}
}
}
Change environment property defaultMinListRowHeight like this:
List {
ForEach(1...10, id: \.self) { i in
Text("\(i)")
}.frame(height: 2)
}.environment(\.defaultMinListRowHeight, 1)

How to add background color to the list view of bottom safe area SwiftUI iOS 14

I'm trying to add background color to the bottom safe area with list view.
I know how to add background color to the list cell, but it doesn't apply to the safe area. Is there any possible way?
Note: I did try ZStack and .edgesIgnoringSafeArea, I need to use SwiftUI 2.0 List View, not LazyVStack or SwiftUI 1.0 (iOS 13) List View
List {
ForEach(0..<100) { index in
Text(String(index))
.listRowBackground(Color.red.edgesIgnoringSafeArea(.all))
}
}
You need to add:
UITableView.appearance().backgroundColor = .clear
and put the List in a ZStack:
#main
struct TestApp: App {
init() {
UITableView.appearance().backgroundColor = .clear
}
var body: some Scene {
WindowGroup {
ZStack {
Color.red.edgesIgnoringSafeArea(.all)
List {
ForEach(0 ..< 100) { index in
Text(String(index))
.listRowBackground(Color.red)
}
}
}
}
}
}
Alternatively instead of using ZStack you can set the color directly:
UITableView.appearance().backgroundColor = UIColor(.red)
Note that this will set the backgroundColor globally.

Turn all Text() on swift app to the same color in SwiftUI

I have used the Text("") object multiple times in my Swift Playground app but I want to change the color of all of them to a specific color (white) without changing each Text property one by one. Is there a way to do this?
Disclaimer: I am programming in a Swift Playground
You can create a custom ViewModifier
struct MyTextModifier: ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(Color.white)
}
}
Then you can apply it to Text where needed, and you only need to change it in the ViewModifier struct.
struct ContentView: View {
var body: some View {
Text("Your Text")
.modifier(MyTextModifier())
}
}
You can create your own View whose body is a Text and that has a color property that you use as the foregroundColor of your Text. If you make the color property static, it will apply to all instances of your View.
You just need to make sure you use ColoredText instead of Text in all places where you want the same color and if you change ColoredText.color, all instances will apply the new text color.
struct ColoredText: View {
#State static var color: Color = .primary
#State var text: String
var body: some View {
Text(text)
.foregroundColor(ColoredText.color)
}
}
if you want to change ALL you can use this:
struct ContentView: View {
var body: some View {
VStack {
Text("Hello World")
Text("aha")
Button(action: {}) {
Text("Tap here")
}
}.colorInvert()
.colorMultiply(Color.red)
}
}

Carousel/sidebar list styles in SwiftUI

There are two list styles that are inactive and produce no result with SwiftUI. Try the .carousel and .sidebar styles to figure it out.
struct ContentView : View {
var body: some View {
List {
Text("Hello")
}
.listStyle(.carousel) // Or .sidebar
}
}
Is this due to the beta (bug), or did I missed something ? The List doesn't appear on my iPhone.
SidebarListStyle is available on macOS only, as CarouselListStyle is only for watchOS.
Here's what sidebar-style list looks like when running on macOS:
Expanded:
Collapsed:
Here's the code (although I'm not sure that an instance of Range or any other one-dimensional sequence is the right choice for this style):
struct ContentView : View {
var body: some View {
List (0..<10) { number in
self.view(forNumber: number)
}
.listStyle(.sidebar)
}
func view(forNumber number: Int) -> some View {
print("number == \(number)")
let ret = Text("#\(number)")
.foregroundColor(.blue)
return ret
}
}
Like others pointed out, the syntax is changing.
Try it this way:
.listStyle(CarouselListStyle())
You're right.
It looks like both .carousel and .sidebar styles are not working / not implemented on iOS.
Here's my demo code:
struct ContentView : View {
#State var alternateStyle = false
var body: some View {
var list =
AnyView(List(0...100) { item in
Text("\(item)").tapAction { self.alternateStyle.toggle() }
}
.navigationBarTitle(Text("A List")))
if alternateStyle {
list = AnyView(list.listStyle(.carousel))
} else {
list = AnyView(list.listStyle(.default))
}
return list
}
}
If you tap on a Text, thus swapping the style, you get a blank list.
SwiftUI is still in beta, hence a lot of components are broken or missing.