状态无法在SwiftUI中正确更新

时间:2020-07-21 10:09:24

标签: ios swift swiftui state combine

正在尝试实现“喜欢和不同”按钮,以允许用户喜欢卡片和不同。当用户喜欢按钮时,id被保存,并且图标从线心变为实心。我可以正确保存id,但是问题是有时图标不会切换为实心图标,无法向用户显示更改,尤其是在选择第一个图标之后。后续卡不会更改状态,而是保持不变,尽管它将正确添加保存id。为了能够看到我必须看到的另一张卡,它与第一张卡不同,它可以同时显示两个卡。我已经尝试过ObservableEnvironmental

我的班级要处理类似的事情

import Foundation
import Disk

class FavouriteRest: ObservableObject {
    @Published private var fav = [Favourite]()
    
    init() {
        getFav()
    }
    
    func getFav(){
        if let retrievedFav = try? Disk.retrieve("MyApp/favourite.json", from: .documents, as: [Favourite].self) {
            fav = retrievedFav
        } else {
            print("")
        }
    }
    
    
    //Get single data
    func singleFave(id: String) -> Bool {
        for x in fav {
            if id == x.id {
               return true
            }
            return false
        }
        return false
    }
    
    func addFav(favourite: Favourite){
        if singleFave(id: favourite.id) == false {
            self.fav.append(favourite)
            self.saveFave()
        }
    }
    
    //Remove Fav
    func removeFav(_ favourite: Favourite) {
        if let index = fav.firstIndex(where: { $0.id == favourite.id }) {
            fav.remove(at: index)
            saveFave()
        }
    }
    
    //Save Fav
    func saveFave(){
        do {
            try Disk.save(self.fav, to: .documents, as: "SmartParking/favourite.json")
        }
        catch let error as NSError {
            fatalError("""
                Domain: \(error.domain)
                Code: \(error.code)
                Description: \(error.localizedDescription)
                Failure Reason: \(error.localizedFailureReason ?? "")
                Suggestions: \(error.localizedRecoverySuggestion ?? "")
                """)
        }
    }
    
}

单张卡

@EnvironmentObject var favourite:FavouriteRest

            HStack(alignment: .top){
                VStack(alignment: .leading, spacing: 4){
                    Text(self.myViewModel.myModel.title)
                        .font(.title)
                        .fontWeight(.bold)
                    Text("Some text")
                        .foregroundColor(Color("Gray"))
                        .font(.subheadline)
                        .fontWeight(.bold)
                }
                Spacer()
                VStack{
                    self.favourite.singleFave(id: self.myViewModel.myModel.id) ? Heart(image: "suit.heart.fill").foregroundColor(Color.red) : Heart(image: "suit.heart").foregroundColor(Color("Gray"))
                }
                .onTapGesture {
                    if self.favourite.singleFave(id: self.myViewModel.myModel.id) {
                        self.favourite.removeFav(Favourite(id: self.myViewModel.myModel.id))
                    } else {
                        self.favourite.addFav(favourite: Favourite(id: self.myViewModel.myModel.id))
                    }
                }
            }

1 个答案:

答案 0 :(得分:0)

如下所示,我可以通过在卡片视图内移动代码并使用import produce from "immer"; import { __ } from "@wordpress/i18n"; import "./editor.scss"; import { RichText, PlainText } from "@wordpress/block-editor"; // import { useState } from "@wordpress/element"; export default function Edit({ attributes, setAttributes, className }) { const services = attributes.services; const onChangeContent = (content, index, type) => { const newContent = produce(services, (draftState) => { draftState.forEach((section) => { if (section.index === index) { section[type] = content; } }); }); setAttributes({ services: newContent }); }; return ( <> {services.map((service) => ( <> <RichText tagName="h3" className={className} value={service.headline} onChange={(content) => onChangeContent(content, service.index, "headline") } /> <PlainText className={className} value={service.description} onChange={(content) => onChangeContent(content, service.index, "description") } /> </> ))} <input className="button button-secondary" type="button" value={__("Add Service", "am2-gutenberg")} onClick={() => setAttributes({ services: [ ...attributes.services, { headline: "", description: "", index: services.length }, ], }) } /> </> ); } 来解决问题。

export default function save({ attributes, className }) {
    const { services } = attributes;

    return (
        <section className={className}>
            {services.length > 0 &&
                services.map((service) => {
                    return (
                        <div className="card-block" data-index={service.index}>
                            <h3>{service.headline}</h3>
                            <div className="card-content">{service.description}</div>
                        </div>
                    );
                })}
        </section>
    );
}

在获取和删除方法中,我更新了@States。现在一切都按预期进行。