SwiftUI WidgetKit Layout Inconsistency: Why does Text Alignment Break in Smaller Widget Sizes?

165 Views Asked by At

I'm new to WidgetKit and I'm trying to create a widget. I've constructed a simple grid to display the days of a month as shown below:

struct extenEntryView : View {
    @Environment(\.widgetFamily) private var widgetFamily
    var entry: SimpleEntry
    
    let daysOfMonth = Array(1...30).map(String.init)
    
    var body: some View {
        let columns = Array(repeating: GridItem(.flexible()), count: 7)
        
        VStack() {
            LazyVGrid(columns:columns, content: {
                ForEach(daysOfMonth, id: \.self) { day in
                    Text(day)
                        .bold()
                        .frame(width: .infinity)
                        .foregroundColor(.orange)
                }
            })
        }
        .environment(\.layoutDirection, .rightToLeft)
        .widgetBackground(Color(.black))
    }
}

When I visualize the widget in different sizes, it behaves inconsistently. The layout especially breaks in the smaller widget sizes. For example, here's the output on a small widget:

Small Widget Output

However, my desired output looks like this (but for the small widget):

Desired Output

As can be seen, the text seems to jump around in the smaller sizes.

  • How can I make this layout more adaptive and consistent across different widget sizes?

My end goal is to have the widget adaptive as a lock screen widget for Ios 16 and above

1

There are 1 best solutions below

0
Priyank javia On

You need to give a fix frame to Text and also need to add minimumScaleFactor. Here is the updated code for the same.

struct extenEntryView : View {
    @Environment(\.widgetFamily) private var widgetFamily
    var entry: SimpleEntry

    let daysOfMonth = Array(1...30).map(String.init)

    var body: some View {
        let columns = Array(repeating: GridItem(.flexible()), count: 7)
    
        VStack() {
            LazyVGrid(columns:columns, content: {
                ForEach(daysOfMonth, id: \.self) { day in
                    Text(day)
                        .bold()
                        .minimumScaleFactor(0.5) //Add minimumScaleFactor here
                        .frame(width: 15,height: 15) //Add fix width and height instead of .infinity
                        .foregroundColor(.orange)
                }
            })
        }
        .environment(\.layoutDirection, .rightToLeft)
        .widgetBackground(Color(.black))
    }
}