Post

Replies

Boosts

Views

Activity

Reply to SwiftUI LazyVGrid Positioning
One more thing, since you are using almost the same set of modifiers on every view, create your own ViewModifier and use that instead. I have made one for you as an example. struct cardModifier: ViewModifier { var fontSize, frameWidth, frameHeight: CGFloat var frameAlignment: Alignment var backgroundColour: Color var backgroundColourOpacity: Double var shadowRadius: CGFloat var foregroundColour: Color var foregroundColourOpacity: Double? var cardText: String var overlayFontSize: CGFloat func body(content: Content) -> some View { content .font(.system(size: fontSize)) .padding() .frame(width: frameWidth, height: frameHeight, alignment: frameAlignment) .background(Rectangle().fill(backgroundColour .opacity(backgroundColourOpacity)) .shadow(radius: shadowRadius)) .cornerRadius(20) .foregroundColor(foregroundColour.opacity(foregroundColourOpacity ?? 1)) .overlay(Text(cardText).foregroundColor(.black).padding() .font(.system(size: overlayFontSize)), alignment: .bottom) } } extension View { func cardStyle(fontSize: CGFloat, frameWidth: CGFloat, frameHeight: CGFloat, frameAlignment: Alignment, backgroundColour: Color, backgroundColourOpacity: Double, shadowRadius: CGFloat, foregroundColour: Color, foregroundColourOpacity: Double? = 1, cardText: String, overlayFontSize: CGFloat) -> some View { modifier(cardModifier(fontSize: fontSize, frameWidth: frameWidth, frameHeight: frameHeight, frameAlignment: frameAlignment, backgroundColour: backgroundColour, backgroundColourOpacity: backgroundColourOpacity, shadowRadius: shadowRadius, foregroundColour: foregroundColour, cardText: cardText, overlayFontSize: overlayFontSize)) } } I had to make this a separate post as I ran out of characters in the first one.
Apr ’23
Reply to SwiftUI LazyVGrid Positioning
Hi, I saw your question a few hours ago and I don't know if you are still looking for an answer at this time. Anyways, here is the solution with an explanation for anyone who might be interested in it. You have a LazyVGrid with two columns which is what you are seeing in the screenshot you've provided. UnitView(), TemperatureView() and CurrencyView() form the first column, whereas DistanceView() and TimeView() form the second column. Since you did not specify the alignment property, it assumed its default value, which is HorizontalAlignment.center in the case of LazyVGrid. If you specify alignment as HorizontalAlignment.leading, then the view would look somewhat like how you want it to look. But, it doesn't look good because the cards are not in the middle of the screen. To solve this, you would have to embed LazyVGrid into a LazyVStack, take the CurrencyView() out of the LazyVGrid, and place it outside LazyVGrid but within LazyVStack. struct ContentView: View { let columns = [ GridItem(.fixed(150), spacing: 30), GridItem(.fixed(150), spacing: 30)] var body: some View { NavigationView{ LazyVStack { LazyVGrid(columns: columns) { NavigationLink(destination: UnitView()) { Image(systemName: "scalemass") .cardStyle(fontSize: 60, frameWidth: 150, frameHeight: 150, frameAlignment: .center, backgroundColour: .purple, backgroundColourOpacity: 0.5, shadowRadius: 3, foregroundColour: .black, cardText: "Weight", overlayFontSize: 22) } NavigationLink(destination: DistanceView()) { Image(systemName: "figure.walk") .cardStyle(fontSize: 60, frameWidth: 150, frameHeight: 150, frameAlignment: .center, backgroundColour: .orange, backgroundColourOpacity: 0.5, shadowRadius: 3, foregroundColour: .black, cardText: "Distance", overlayFontSize: 22) } NavigationLink(destination: TemperatureView()) { Image(systemName: "thermometer.sun") .cardStyle(fontSize: 56, frameWidth: 150, frameHeight: 150, frameAlignment: .center, backgroundColour: .yellow, backgroundColourOpacity: 0.5, shadowRadius: 3, foregroundColour: .black, cardText: "Temperature", overlayFontSize: 21) } NavigationLink(destination: TimeView()) { Image(systemName: "clock") .cardStyle(fontSize: 60, frameWidth: 150, frameHeight: 150, frameAlignment: .center, backgroundColour: .blue, backgroundColourOpacity: 0.5, shadowRadius: 3, foregroundColour: .black, cardText: "Time", overlayFontSize: 21) } } NavigationLink(destination: CurrencyView()) { Image(systemName: "dollarsign.square.fill") .cardStyle(fontSize: 90, frameWidth: 330, frameHeight: 150, frameAlignment: .top, backgroundColour: .green, backgroundColourOpacity: 0.4, shadowRadius: 10, foregroundColour: .white, cardText: "Currency Converter", overlayFontSize: 27) } } } } } Notice that the CurrencyView() is not in the LazyVGrid anymore. So, it is not in the first column. Now it looks exactly like you wanted. I hope this helps you! Thank you!
Apr ’23