Я пытаюсь добавить черный градиентный фон поверх моего 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) }
}
}
}