Skip to content

Unable to use url-image as header background #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Cacauu opened this issue Jan 17, 2022 · 2 comments
Open

Unable to use url-image as header background #2

Cacauu opened this issue Jan 17, 2022 · 2 comments

Comments

@Cacauu
Copy link

Cacauu commented Jan 17, 2022

I use the url-image library in one of the apps I'm building to load images from a server into a SwiftUI Image view. I've tried to migrate the view to use the ScrollViewReactiveHeader and put the URLImage into the header part of it - without any success. The view always displays with 0 height, therefore making the ScrollViewReactiveHeader invisible. See below for a snippet that shows how I'm trying to use both libraries together:

var body: some View {
        NavigationView {
            ScrollViewReactiveHeader(header: {
               URLImage(url) { image in
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .scaledToFill()
                        .clipped()
                        .frame(height: 300)
                }
            }, headerOverlay: {
                [...]
            }, body: {
                [...]
            }, configuration: .init(showStatusBar: true, backgroundColor: nil))
        }
    }

I've also tried wrapping the URLImage in a VStack with a fixed height but that didn't help either. I'd be happy if you could provide any hints on what to do or where the problem might be :)

@trentguillory
Copy link
Member

trentguillory commented Jan 17, 2022

Hey, thanks for reaching out. This is an issue that's been previously reported to me (not through Github Issues). From what I've seen, AsyncImage and URLImage report back a nil height to enclosing GeometryReaders, even after their content has loaded. I'm not sure why this is.

I do know that Kingfisher works as expected, though - after loading, the height is accurate and will be displayed properly inside of ScrollViewReactiveHeader. I'll be doing more testing of this myself when I get the chance, but I'm worried that it's outside the scope of our control with this library.

As for your simplified test of wrapping the URLImage in a VStack, I've noticed oddities with that too. The best simple test that works is to use truly static views. Either a rectangle with a set height or an Image with a local asset - these work as expected.

The best workaround I can provide at the moment is to import Kingfisher for remote images. Let me know how that goes!

@Cacauu
Copy link
Author

Cacauu commented Feb 5, 2022

Hey, thank you for getting back to this! I only now got around to test Kingfisher. Sadly, it still doesn't work as expected. I have tried the ScrollViewReactiveHeader with static images (just normal Image in SwiftUI, no other library) with no problem, but anything that loads from remote sources doesn't seem to work. I have once again added the Kingfisher code to this. Another probably helpful Information is that, if I pass an empty body to the ScrollViewReactiveHeader, it loads the header background and displays it centered in the View.

I was also wondering if this might be related to the fact that I'm loading content for the body property after initially showing the view. The body shows a placeholder at first and then switches to a list (as you can see in the code). I hope this helps you to better understand what I'm doing and maybe helps to solve this problem 😊

var body: some View {
        NavigationView {
            ScrollViewReactiveHeader(header: {
                VStack {
                    if let angebot = someOptional {
                        KFImage(angebot.imageURL)
                            .placeholder {
                                Image(systemName: "arrow.2.circlepath.circle")
                                    .font(.largeTitle)
                                    .opacity(0.3)
                            }
                            .retry(maxCount: 3, interval: .seconds(5))
                            .resizable()
                            .aspectRatio(contentMode: .fill)
                            .scaledToFill()
                            .clipped()
                            .frame(height: 300)
                            .frame(minWidth: 0, maxWidth: .infinity)
                        
                    } else {
                        Image("someImage")
                            .resizable()
                            .aspectRatio(contentMode: .fill)
                            .scaledToFill()
                            .clipped()
                            .frame(height: 300)
                    }
                    Spacer()
                }
                .frame(height: 300)
            }, headerOverlay: {
                VStack(alignment: .leading) {
                    Spacer()
                    Text("\(anotherOptional ?? "Der Eisbus ist für euch unterwegs!")")
                        .font(Font.headline.bold())
                        .multilineTextAlignment(.leading)
                        .padding()
                        .foregroundColor(Color("EisbusStyledText"))
                        .frame(minWidth: 0, maxWidth: .infinity)
                        .materialBackground()
                }
                .frame(height: 300)
                .frame(minWidth: 0, maxWidth: .infinity)
            }, body: {
                    if model.state == .upToDate {
                        VStack {
                            Picker("...", selection: $selectedView) {
                                Text("Eissorten").tag(0)
                                Text("Eisspezialitäten").tag(1)
                            }
                            .pickerStyle(.segmented)
                            .padding(.leading)
                            .padding(.trailing)
                            .padding(.top)
                            if selectedView == 0 {
                                EissortenList(anOptionalArray ?? [], kugelPreis: moreOptionals ?? 99.9, sahnePreis: andMoreOptionals ?? 99.9, bus: bus)
                                    .frame(minHeight: 0, maxHeight: .infinity)
                            } else if selectedView == 1 {
                                SomeList(eisbecher: anotherOptionalArray ?? [])
                            }
                            #if DEBUG
                                Text("Bus: \(bus)")
                            #endif
                        }
                    }
                    else {
                        VStack(alignment: .center) {
                            Spacer()
                            GenericPlaceholder()
                            if self.model.state == .error {
                                Text("Fehler beim Aktualisieren!")
                            } else {
                                Text("Lädt...")
                            }
                        }
                        .padding()
                    }
            }, configuration: .init(showStatusBar: true, backgroundColor: nil))
                .navigationBarItems(leading:
                    Button("Fertig") {
                        DispatchQueue.main.async {
                            self.presentationMode.wrappedValue.dismiss()
                        }
                    })
                    .navigationBarTitle(Text("..."), displayMode: .inline)
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants