Medium Widget Size Background Image or Color not filling the entire space

114 Views Asked by At

When trying to create a widget with minimal IOS 14, the background color or image refuses to fill the widget on the sides. It works with containerBackground Modifier, but it's for IOS 17 or newer. I also saw the same question, but the answer from there now working for some reason, even if I copy the exact same code: enter image description here

struct WidgetEntryView : View {
var entry: SomeEntry
var body: some View {
    VStack(alignment: .leading) {
        Spacer()
        Text("Aardvark Exactlywhat")
            .font(.largeTitle)
            .bold()
            .padding(.bottom, 20)
            .padding(.leading, 20)
            .padding(.trailing, 20)
            .minimumScaleFactor(0.5)
            .foregroundColor(.white)
            .shadow(
                color: Color.black,
                radius: 1.0,
                x: CGFloat(4),
                y: CGFloat(4))
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)   // << this one !!
    .edgesIgnoringSafeArea(.all)
    .background(
        backgroundImage()
            .resizable()
            .scaledToFill()
    )
}
2

There are 2 best solutions below

0
Timmy On BEST ANSWER

You need to create a wrapper function that uses .containerBackground when available and falls back to using .background when needed:

extension View {
    @ViewBuilder func widgetBackground<T: View>(@ViewBuilder content: () -> T) -> some View {
        if #available(iOS 17.0, *) {
            containerBackground(for: .widget, content: content)
        }else {
            background(content())
        }
    }
}

Usage:

.widgetBackground {
    backgroundImage()
        .resizable()
        .scaledToFill()
}
1
Benzy Neez On

A workaround is to add negative horizontal padding to the image.

I measured the gap to be 16pt, but if the image is just a space filler and it doesn't matter if there is generous overflow then you could make it bigger as a precaution.

.background(
    backgroundImage()
        .resizable()
        .scaledToFill()
        .padding(.horizontal, -16)
)