Reputation: 1108
I can't seem to find a way to create spacing between List
items.
Maybe I shouldn't put in a list in the first place?
What do you think?
This the code that generates the view:
struct ContentView: View {
@ObservedObject var ratesVM = RatesViewModel()
init() {
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.white]
UITableView.appearance().backgroundColor = UIColor.init(named: "midnight blue")
UITableViewCell.appearance().backgroundColor = .green
UITableView.appearance().separatorStyle = .none
}
var body: some View {
NavigationView {
List (ratesVM.ratesList, id: \.self) { rate in
Image(systemName: "plus")
Button(action: {print("pressed")}) {
Text(rate.hebrewCurrencyName)
}
}
.navigationBarTitle("המרות מטבע")
.navigationBarItems(leading:
Button(action: {
print("button pressed")
self.ratesVM.callService()
}) {
Image(systemName: "plus")
.foregroundColor(Color.orange)})
}.environment(\.layoutDirection, .rightToLeft)
}
}
Upvotes: 25
Views: 45257
Reputation: 11
** For Swift 5 **
In my case, only need to add, two properties to my code listRowSeparator()
and listRowSpacing()
. The first one was used inside of ForEach
and the second one was used at the end of List View.
var content: some View {
List {
Section {
ForEach (itemList) { item in
ScheduledTransfer365Row(item: item)
.listRowSeparator(.hidden)
}
}
}
.listRowSpacing(2)
}
Upvotes: 1
Reputation: 530
In my case I needed to add the following to my Section
:
List {
Section {
ForEach(nearbyLocations, id: \.id) { location in
LocationCard(location: location)
}
}
.listRowSeparator(.hidden)
}
.listStyle(.plain)
.listRowBackground(Color.clear)
.listRowSpacing(10)
To change the spacing of the cards, update the listRowSpacing
as needed.
Posting this here incase someone needs a similar result.
Upvotes: 11
Reputation: 5550
Working example
struct AuthView_Previews: PreviewProvider {
static var previews: some View {
let t = ["1","2","3","4","5","6","7","8","9"]
GeometryReader { geometry in
List(t, id: \.self){ item in
HStack{
Text(item)
}
.frame(width: geometry.size.width - 40, height: 39, alignment: .center)
.padding(10)
.background(Color("AppRecommended"))
.cornerRadius(10)
.listRowSeparator(.hidden)
}
.listStyle(.plain)
}
}
}
Note: .listRowSeparator(.hidden) works for iOS 15 and above
Upvotes: 0
Reputation: 834
You can achieve it by removing the list row separators .listRowSeparator(.hidden)
and setting the list row background to an InsettableShape .listRowBackground()
defining top and bottom EdgeInsets padding. Btw, don't forget to set the .listStyle(.plain)
to .plain
.
You can find a better implementation on this dev post SwiftUI List Card View.
//
// ContentView.swift
// My App
//
// Created by Kolmar Kafran on 25/08/22.
// https://www.linkedin.com/in/kolmar-kafran/
//
import SwiftUI
struct ContentView: View {
@State private var someList = [0, 1, 2, 3, 4]
var body: some View {
List {
ForEach(someList, id: \.self) { n in
Text("\(n)")
.foregroundColor(.white)
.listRowBackground(
RoundedRectangle(cornerRadius: 5)
.background(.clear)
.foregroundColor(.blue)
.padding(
EdgeInsets(
top: 2,
leading: 10,
bottom: 2,
trailing: 10
)
)
)
.listRowSeparator(.hidden)
}
.onDelete { idx in
someList.remove(atOffsets: idx)
}
}
.listStyle(.plain)
}
}
Upvotes: 12
Reputation: 19339
A quick solution here is to just set the corresponding listStyle
to SidebarListStyle
. For instance:
List {
Text("First row")
Text("Second row")
Text("Third row")
}
.listStyle(SidebarListStyle())
But please note that on macOS and iOS, the sidebar list style also displays disclosure indicators in the section headers that allow the user to collapse and expand sections.
Another quick alternative would be to use the Divider()
helper view instead (i.e., a visual element that can be used to separate other content):
List {
Text("First row")
Divider()
Text("Second row")
Divider()
Text("Third row")
}
Both solutions won't allow direct control of the vertical spacing but at least provides a more spacious layout alternative.
Upvotes: 0
Reputation: 1108
padding didn't work since it only increased the size of the item/cell and not the spacing between, but .environment(.defaultMinListRowHeight, 20) seemed to work
I also implemented a custom view for the button styling to adjust the frame and "pressable area" of the button relative to the item/cell.
struct MyButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundColor(.black)
.opacity(configuration.isPressed ? 0.5 : 1.0)
.frame(width: 350, height: 50, alignment: Alignment.center)
.background(Color.orange)
}
}
struct ContentView: View {
@ObservedObject var ratesVM = RatesViewModel()
init() {
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.white]
UITableView.appearance().backgroundColor = UIColor.init(named: "midnight blue")
UITableViewCell.appearance().backgroundColor = .clear
UITableView.appearance().separatorStyle = .none
}
var body: some View {
NavigationView {
List (ratesVM.ratesList, id: \.self) { rate in
Button(action: {print("pressed")}) {
Text(rate.hebrewCurrencyName)
}.buttonStyle(MyButtonStyle())
}
.navigationBarTitle("המרות מטבע")
.navigationBarItems(leading:
Button(action: {
print("button pressed")
self.ratesVM.callService()
}) {
Image(systemName: "plus")
.foregroundColor(Color.orange)})
}.environment(\.layoutDirection, .rightToLeft)
.environment(\.defaultMinListRowHeight, 150)
}
}
Upvotes: 2
Reputation: 4209
You can define the minimum list row height to be bigger so you'll have more separation between rows.
List (ratesVM.ratesList, id: \.self) { rate in
Image(systemName: "plus")
Button(action: {print("pressed")}) {
Text(rate.hebrewCurrencyName)
}
}.environment(\.defaultMinListRowHeight, 50) //minimum row height
Alternatively you can build your row as a HStack and specify a frame height.
List (ratesVM.ratesList, id: \.self) { rate in
HStack {
Image(systemName: "plus")
Button(action: {print("pressed")}) {
Text(rate.hebrewCurrencyName)
}
}.frame(height: 50) //your row height
}.environment(\.defaultMinListRowHeight, 20)
Or as a VStack and and use Spacers
List (ratesVM.ratesList, id: \.self) { rate in
VStack{
Spacer()
HStack {
Image(systemName: "plus")
Button(action: {print("pressed")}) {
Text(rate.hebrewCurrencyName)
}
}
Spacer()
}.frame(height: 50)
}.environment(\.defaultMinListRowHeight, 20)
Upvotes: 17
Reputation: 14397
SwiftUI lets us set individual padding around views using the padding() modifier. If you use this with no parameters you’ll get system-default padding on all sides, like this:
VStack {
Text("SwiftUI")
.padding()
Text("rocks")
}
But you can also customize how much padding to apply and where. So, you might want to apply system padding to only one side:
Text("SwiftUI")
.padding(.bottom)
Or you might want to control how much padding is applied to all sides:
Text("SwiftUI")
.padding(100)
Or you can combine the two to add a specific amount of padding to one side of the view:
Text("SwiftUI")
.padding(.bottom, 100)
so you can do
Text(rate.hebrewCurrencyName)
.padding(50)
Upvotes: 1