I have LazyVGrid in which i want to make 2 item per row for iPhone and 4 per row in iPad, I am not sure how should i give condition in SwiftUI and how to restrict number of rows
//
// ContentView.swift
// DemoProject
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: Item.timestamp, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
private var gridItemLayout = [GridItem(.adaptive(minimum: 100))]
@StateObject private var viewModel = HomeViewModel()
var body: some View {
GeometryReader { geometry in
NavigationView {
ScrollView {
LazyVGrid(columns: gridItemLayout, spacing: 20) {
ForEach(viewModel.results, id: .self) {
let viewModel = ResultVM(model: $0)
NavigationLink(destination: {
DetailView()
}, label: {
SearchResultRow(resultVM: viewModel)
})
}
}
}
}
.onAppear(perform: {
viewModel.performSearch()
})
}
}
}
struct SearchResultRow: View {
let resultVM: ResultVM
var body: some View {
HStack {
RoundedRectangle(cornerRadius: 16).fill(.yellow)
.frame(maxWidth: .infinity).aspectRatio(1, contentMode: .fit)
.overlay(Text(resultVM.trackName))
.onTapGesture {
}
}.padding()
.background(Color.red)
}
}
3
Answers
Well you can make your
gridItemLayout
to the following:And add in an init (recommended) or in
.onAppear
:Something like this:
While the provided answers will work per se they can get tricky when using your app in a multitasking mode on the iPad: Split View or Slide Over. In case of Slide Over the width of your app on the iPad will be the same as it would be on the iPhone but if you’ll check for the interface idiom, you’ll still get
.pad
(well, cause you are using iPad). And the interface therefore might get broken – you’ll get an iPad interface on an iPhone-sized app.But there’s a way to do it right –
UserInterfaceSizeClass
. Specifically you’ll need a horizontal size class. This enum has 2 cases (state of February 2023):.compact
and.regular
. In simple words theUserInterfaceSizeClass
is.compact
when the width of an app is similar to the iPhone’s width (Slide Over or Slit View in Portrait Mode or just an actual iPhone) and.regular
when the width is similar to the iPad’s width (normal iPad Portrait or Landscape mode, Split View in Landscape Mode). Based on this parameter you can decide how to render your interfaceSo, enough theory, here’s the code to copy-paste 🙂