My View постоянно отрисовывается в SwiftUI - PullRequest
0 голосов
/ 20 июня 2020

Вот мое мнение:

struct EditProfile: View {
    @State var bio = UserDefaults.standard.string(forKey: "bio") ?? "Edit your bio"
    @ObservedObject var storage = FirebaseStorage()
    @State var text = ""
    let photos = ["img1", "img2", "img3"]
    var body: some View {
        VStack {
            Text("Photos")
            .font(Font.system(size: 21))
            .fontWeight(.bold)
            HStack {
                ForEach(photos, id: \.self){ img in
                    EditableCircleImage(kfImage: self.storage.makeCircleImage(str: img))
                }
            }
            .background(
                RoundedRectangle(cornerRadius: 10)
                    .fill(Color.white)
                    .shadow(color: .gray, radius: 1, x: 0, y: 1)
            )

            Text("Bio")
                .font(Font.system(size: 21))
                .fontWeight(.bold)
            MultiTextField(txt: $text)
                .padding(10)
                .cornerRadius(20.0)
                .background(
                    RoundedRectangle(cornerRadius: 10)
                        .fill(Color.white)
                        .shadow(color: .gray, radius: 1, x: 0, y: 1)
                )
                .border(Color.gray.opacity(0.5), width: 1)

        }.padding(20).background(Color.gray.opacity(0.1))
    }
}

Вот EditableCircleImage():

struct EditableCircleImage: View {
    let kfImage: KFImage
    var body: some View {
        ZStack {
            kfImage
                .resizable()
            .scaledToFit()
            .frame(height: 200)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.orange, lineWidth: 2))
            Button(action: {}){
                Image(systemName: "pencil.circle.fill")
                    .resizable()
                    .scaledToFit()
                    .frame(height: 40)
                .foregroundColor(.gray)

            }.offset(x: 40, y: 50)
        }
    }
}

Вот модель, которая возвращает изображение: FirebaseStorage.swift:

class FirebaseStorage: ObservableObject {
    let storage = Storage.storage()
    let uid = UserAuth().uid ?? "<uid>"
    @Published var img1 = UserDefaults.standard.string(forKey: "img1") ?? "<img1>"

    func makeCircleImage(str: String) -> KFImage {
        if let url = UserDefaults.standard.string(forKey: str) {
            print("not nil: \(str)")
            return KFImage(URL(string: "http://app-23c8s.appspot.com.storage.googleapis.com/users/\(uid)/\(url)"))
        }
        else {
            print("is nil: \(str)")
            return KFImage(source: nil)
        }

    }
}

Операторы печати в модели выше печатаются снова и снова, даже если никакие значения не изменились после первоначального рендеринга. Есть идеи, почему?

Постоянно печатает:

not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3
not nil: img1
is nil: img2
is nil: img3

ОБНОВЛЕНИЕ:

Я изменил:

ForEach(photos, id: \.self){ img in
    EditableCircleImage(kfImage: self.storage.makeCircleImage(str: img))
}

на

EditableCircleImage(kfImage: self.storage.makeCircleImage(str: "img1"))

и теперь печатает:

not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1
not nil: img1

Ответы [ 3 ]

0 голосов
/ 20 июня 2020

Похоже, что

func makeCircleImage(str: String) -> KFImage { ... }

- это асинхронная функция, в частности KFImage (..). Вы используете это в:

ForEach(photos, id: \.self){ img in
     EditableCircleImage(kfImage: self.storage.makeCircleImage(str: img))
}

Вероятно, это источник проблемы. Вам действительно следует подождать, пока у вас не будут все изображения, прежде чем использовать их, особенно в режиме просмотра.

0 голосов
/ 21 июня 2020

Изменение моего кода на этот:

struct EditProfile: View {
    @State var bio = UserDefaults.standard.string(forKey: "bio") ?? "Edit your bio"
    @ObservedObject var storage = Storages()
    @State var text = ""
    let uid = UserAuth().uid ?? "<uid>"
    let photos: [String:String] = [
        "img1": UserDefaults.standard.string(forKey: "img1") ?? "",
        "img2": UserDefaults.standard.string(forKey: "img2") ?? "",
        "img3": UserDefaults.standard.string(forKey: "img3") ?? "",
    ]
    var body: some View {
        VStack {
            Text("Points")
            .font(Font.system(size: 21))
            .fontWeight(.bold)
            HStack {
                ForEach(photos.sorted(by: <), id: \.key){ (key,val) in
                    EditableCircleImage(
                        kfImage: KFImage(
                            URL(string: "http://app-23c8s.appspot.com.storage.googleapis.com/users/\(self.uid)/\(val)")
                        ),
                        key: key
                    )
                }
            }

struct EditableCircleImage: View {
    let kfImage: KFImage
    let key: String
    var body: some View {
        ZStack {
            kfImage

устраняет проблему.

0 голосов
/ 20 июня 2020

Убрать соответствие класса FirebaseStorage ObservableObject и удалить оболочку свойства @ObservedObject из @ObservedObject var storage = FirebaseStorage(). Удалите также оболочку свойств @Published. Запустите его и дайте мне знать, если проблема не исчезнет. Кстати, мне непонятно, почему вы сделали класс соответствующим ObservableObject и почему вы использовали оболочку свойств в этом конкретном c варианте использования. Если я чего-то упускаю, дайте мне знать. Предполагается, что этот пост включает весь код проблемы, о которой вы говорите. Надеюсь, это вам поможет.

...