Наложение градиента работает на stati c Image, но не загружается Image из сети - PullRequest
3 голосов
/ 12 июля 2020

Я пытаюсь добавить черный градиентный фон поверх моего img1 ниже:

struct Match: View {
    let storage = Storages()
    @ObservedObject var info = Info()
    @State var name: Text = Text("")
    @State var age: Text = Text("")
    @State var bio: Text = Text("")
    @State var img1: Image? = nil
    @State var img2: Image? = nil
    @State var img3: Image? = nil
    var body: some View {
        VStack {
            ScrollView(.vertical, showsIndicators: true) {
                ZStack(alignment: .bottomLeading){
                    LinearGradient(gradient: Gradient(colors: [Color.black.opacity(0.5), Color.black]), startPoint: .top, endPoint: .bottom)
                    img1?.resizable().scaledToFit()
                    name
                        .font(.system(size: 30))
                        .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
                        .foregroundColor(.white)
                        .multilineTextAlignment(.leading)
                        .padding(EdgeInsets(top: 0, leading: 35, bottom: 55, trailing: 0))
                    age
                        .font(.system(size: 30))
                        .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
                        .foregroundColor(.white)
                        .multilineTextAlignment(.leading)
                        .padding(EdgeInsets(top: 0, leading: 35, bottom: 20, trailing: 0))
                }.background(Color.orange)
                bio
                    .padding()
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
                    .background(
                        Rectangle()
                            .foregroundColor(.white)
                    )
                    
                    .foregroundColor(.black)
                img2?.resizable().scaledToFit()
                img3?.resizable().scaledToFit()
            }.background(
                RoundedRectangle(cornerRadius: 15)
                    .foregroundColor(Color("LightBlack70%"))
            ).clipShape(
                RoundedRectangle(cornerRadius: 15)
            ).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
    }
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
    .onAppear{
        let match = Info().getMatch()
        guard let uid = match["uid"] else {
            return
        }
        self.bio = Text(match["bio"] as? String ?? "")
        self.name = Text(match["name"] as? String ?? "")
        self.age = Text(match["age"] as? String ?? "")
        print("onAppear() matchImg1: \(match["img1"]!) ")
        if let matchImg1 = match["img1"], let uid = match["uid"] {
            self.storage.loadImageFromUrl(uid: uid as? String, imgName: matchImg1 as? String){ self.img1 = $0 }
        }
        if let matchImg2 = match["img2"]{
            self.storage.loadImageFromUrl(uid: uid as? String, imgName: matchImg2 as? String){ self.img2 = $0 }
        }
        if let matchImg3 = match["img3"]{
            self.storage.loadImageFromUrl(uid: uid as? String, imgName: matchImg3 as? String){ self.img3 = $0 }
        }
    }
    }
}

Однако он не отображается. Если я изменю img1 на изображение stati c, хранящееся в моем Assets.xcassets, градиент будет работать. Но в приведенном выше коде я загружаю изображение из сети, и это, похоже, влияет на визуализируемый градиент.

Есть идеи, в чем проблема?

Storages.swift

class Storages: ObservableObject {
    let storage = Storage.storage()
    let uid = UserAuth().uid ?? "<uid>"
    @Published var img1 = UserDefaults.standard.string(forKey: "img1") ?? "<img1>"
    @Published var photos: [String:String?] = [
        "img1": UserDefaults.standard.string(forKey: "img1"),
        "img2": UserDefaults.standard.string(forKey: "img2"),
        "img3": UserDefaults.standard.string(forKey: "img3"),
    ]

    func replaceImage(key: String, uiImage: UIImage){
        guard let data = uiImage.jpegData(compressionQuality: 0.8) else {
            return
        }
        // set upload path
        let metaData = StorageMetadata()
        metaData.contentType = "image/jpg"
        
        let filename = "\(randomAlphanumeric()).jpg"
        print("upload filename: \(filename)")
        let ref = self.storage.reference().child("users/\(self.uid)/\(filename)")
        // Upload the file to the path "images/rivers.jpg"
        let uploadTask = ref.putData(data, metadata: metaData) { (metadata, error) in
            print("upload task: \(metadata)")
            print("error: \(error)")
          guard let metadata = metadata else {
            // Uh-oh, an error occurred!
            return
          }
            UserDefaults.standard.set(filename, forKey: key)
        }
        
    }
    
    func loadImageFromUrl(uid: String? = Storages().uid, imgName: String?, completion: @escaping (Image)->()) {
        guard let imgName = imgName, let uid = uid else {
            return
        }
        guard let url = URL(string: "http://app-4j34s.appspot.com.storage.googleapis.com/users/\(uid)/\(imgName)") else {
            return
        }
        URLSession.shared.dataTask(with: url){ data, response, err in
            if let data = data, let uiImage = UIImage(data: data)  {
                DispatchQueue.main.async {
                    completion(Image(uiImage: uiImage))
                }
            }
            
        }.resume()

    }
}

ContentView.swift

struct ContentView: View {
    @ObservedObject var auth = UserAuth()
    var body: some View {
        Group {
            if auth.uid != nil { Match() } else { LoginView(auth: auth) }
        }
    }
}
...