简体   繁体   中英

SwiftUI background default to gradient

I am trying to set a background with an image and if there is no image to default to a gradient, the thing is that I have not found a way to put an if inside the declarative part of SwiftUI, and I cannot use a function since Image does not conform to View. Has anyone a solution to set conditionally the background to an image and if not possible to set it to a color?

struct ReminderView: View {

var reminder: Reminder

var bgImage: Image? {
    if let data = reminder.image, let image = UIImage(data: data) {
        return Image(uiImage: image).resizable()
    }
    return nil
}

var bg: LinearGradient {
    return LinearGradient(gradient: Gradient(colors: [
    Color(.sRGB, red: 38 / 255, green: 63 / 255, blue: 159 / 255, opacity: 1),
    Color(.sRGB, red: 174 / 255, green: 77 / 255, blue: 1, opacity: 1)]),
                               startPoint: UnitPoint(x: 0, y: 1), endPoint: UnitPoint(x: 1, y: 0))
}

var body: some View {
    GeometryReader { (geometry) in
        VStack(alignment: .center, spacing: 0) {
            Group {
                Spacer()
                Spacer()
            }.shadow(color: .gray, radius: 5, x: 0, y: 0)
        }.frame(width: geometry.size.width,
                height: geometry.size.width / CGFloat(Card.aspectRatio))
            .background((self.bgImage != nil) ? self.bgImage! : self.bg)
            .cornerRadius(10)
            .shadow(radius: 10)
    }
}
}

The thing is I've tried this also and does not work:

var bgImage: some View {
    if let data = reminder.image, let image = UIImage(data: data) {
        return Image(uiImage: image).resizable()
    }
    return LinearGradient(gradient: Gradient(colors: [
    Color(.sRGB, red: 38 / 255, green: 63 / 255, blue: 159 / 255, opacity: 1),
    Color(.sRGB, red: 174 / 255, green: 77 / 255, blue: 1, opacity: 1)]),
                               startPoint: UnitPoint(x: 0, y: 1), endPoint: UnitPoint(x: 1, y: 0))
}

It says: Function declares an opaque return type, but the return statements in its body do not have matching...

It is due to different types of views you try to set into background. There is simple approach to solve this:

.background((self.bgImage != nil) ? AnyView(self.bgImage!) : AnyView(self.bg))

Actually you can't return AnyView with the above lines of code. If you want to return any type of UIComponents, you can do like this :

struct ContentView: View {
    var body: some View {
        VStack {
            decicidedView(data: nil)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

func decicidedView(data:Data?) -> AnyView {
    if data == nil {
        return AnyView(Image("abc.png"))
    } else {
        return AnyView(Image("abc.png").background(LinearGradient(gradient: Gradient(colors: [.white, .black]), startPoint: .top, endPoint: .bottom)))
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM