skip to Main Content

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

Answers


  1. 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)
    )
    
    Login or Signup to reply.
  2. 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()
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search