Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
404 views
in Technique[技术] by (71.8m points)

swift - SwiftUI, can't load the image by URL with PageTabViewStyle

Hi I'm struggling with the problem that I can't load image in TabView

I wanted to make page view so I try to use TabView() and PageTabViewStyle.

and I also use KingFisher library to load image by URL.

When I wrote code like below, this code is not working. :

TabView() {
        KFImage(URL(string: <ADDRESS for IMAGE>)!)
               .resizable()
               .clipped()
               .frame(width: width_screen, height: height_banner, alignment: .topLeading)
    }
    .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))

I had doubt about KFImage but if the KFImage scope is out of TabView(), it works well. When I wrote code like below, it works well.

var body: some View {
    TabView() {
        ...
    }

    KFImage(URL(string: "<ADDRESS for IMAGE>")!)
                        .resizable()
                        .clipped()
                        .frame(width: width_screen, height: height_banner, alignment: .topLeading)
}

I wonder how to present image in this tabview. Or I should construct custom view to make paging view.

question from:https://stackoverflow.com/questions/65879941/swiftui-cant-load-the-image-by-url-with-pagetabviewstyle

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I think it is about async operation. I come up with this solution;

in view:

@State private var image: UIImage? = nil

in body:

TabView() {
        Image(uiImage: image ?? UIImage(named: "defaultImage")!)
            .resizable()
            .clipped()
            .frame(width: 250, height:200, alignment: .topLeading)
            .onAppear(perform: {
                fetchImage()
            })
            
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))

*I used "UIImage(named: "defaultImage")!" and "width: 250, height:200" but you can replace them with yours.

in view:

    private func fetchImage() {
    if let url = URL(string: imageUrl) {
        KingfisherManager.shared.retrieveImage(with: url) { result in
            let image = try? result.get().image
            if let image = image {
                self.image = image
            }
        }
    }
}

Another solution without using Kingfisher would be like;

    TabView() {
        if let url = URL(string: imageUrl) {
            if let imageData: NSData = NSData(contentsOf: url) {
                if let image = UIImage(data: imageData as Data) {
                    Image(uiImage: image)
                        .resizable()
                        .clipped()
                        .frame(width: 250, height:200, alignment: .topLeading)
                }
            }
        }
    }
    .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))

This works well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...