Изменение состояния обновляет только некоторые представления

#swiftui

#swiftui

Вопрос:

Прилагаемая программа не изменяет QR-код в QRView, когда пользователь изменяет URL-адрес в текстовом поле, однако текстовое представление под QR-кодом обновляется. Чего мне не хватает?

Я попробовал это без текстового поля, а также добавил / заменил MapView, чтобы посмотреть, сработает ли другое представимое представление. Просмотр карты также не сработал, и удаление текстового представления ничего не изменило.

 import SwiftUI
import CoreImage.CIFilterBuiltins

struct ContentView: View
{
    @State var url = "https://www.nytimes.com"
    var body: some View
    {
        VStack
        {
            Spacer()
            QRView(string: "URL:(url))")
            Text(url)
            Spacer()
            HStack
            {
                Text("URL")
                TextField("URL",text: $url)
            }
            .padding()
        }
    }
}

struct QRView: View
{
    @State var string:String
    
    var body: some View
    {
        Image(uiImage: generateQRCode(from: string))
            .interpolation(.none)
            .resizable()
            //.aspectRatio(contentMode: .fit)
            .frame(width: 200, height: 200)
    }
}

//MARK:- QRCode

func generateQRCode(from string: String) -> UIImage
{
    let context = CIContext()
    let filter = CIFilter.qrCodeGenerator()
    
    let data = Data(string.utf8)
    filter.setValue(data, forKey: "inputMessage")
    
    if let outputImage = filter.outputImage {
        if let cgimg = context.createCGImage(outputImage, from: outputImage.extent)
        {
            return UIImage(cgImage: cgimg)
        }
    }
    
    return UIImage(systemName: "xmark.circle") ?? UIImage()
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
 

Ответ №1:

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

 struct QRView: View
{
    var string: String      // << here !!

// .. other code
}