更改结构模型中的值。

5 浏览
0 Comments

更改结构模型中的值。

我遇到了一个问题,即将结构中的项目添加到收藏夹中。想法如下:

  • 我有一个带有卡片数据的json
  • 在主屏幕上,应用程序显示一个随机卡片
  • 用户可以选择另一张随机卡片或将其保存到收藏夹中。

以下是代码。

  1. 创建CardModel(文件1):

struct CardModel:Hashable,Codable,Identifiable {

let id:Int

let topic:String

let category:String

var saved:Bool

}

  1. 从json中检索数据并创建结构数组(文件2):

var cardsModelArray:[CardModel] = load(“LetsTalkTopics.json”)

  1. 从数组中随机选择项目的功能(文件3):

func pickRandomCard()-> CardModel {

let randomCard = cardsModelArray.randomElement()!

返回randomCard

}

  1. 更改“saved”布尔值的功能(文件4)

func saveCard(card:CardModel){

let index = card.id

cardsModelArray[index] = CardModel(id:index,topic:card.topic,category:card.category,saved:!card.saved)

}

  1. 查看文件(文件5,简化)

import SwiftUI

struct StackOverFlow:View {

@State var currentCard = pickRandomCard()

var body:some View {

VStack {

CardViewStackOver(cards:currentCard)

Button(“显示随机卡片”){

currentCard = pickRandomCard()

}

Button(“保存项目”){

saveCard(card:currentCard)

}

}

}

struct StackOverFlow_Previews:PreviewProvider {

static var previews:some View {

NavigationView {

StackOverFlow()

}

}

}

struct CardViewStackOver:View {

let cards:CardModel

var body:some View {

VStack {

Text(cards.topic)

Text(cards.category)

Text(String(cards.id))

HStack {

if cards.saved {

Image(systemName:“heart.fill”)

.font(.title)

.padding(15)

.padding(.bottom,20)

} else {

Image(systemName:“heart”)

.font(.title)

.padding(15)

.padding(.bottom,20)

}

}

}

}

}

但是我肯定做错了什么,在单独的视图中,我展示了保存的卡片,但它不起作用(显示一些随机卡片,并且一些保存的卡片有重复)。通过我的研究,我发现结构是不可变的,当我尝试编辑一个值时,基本上Swift会创建一个副本并对副本进行更改。如果是这样,创建此收藏功能的正确方法是什么?

0
0 Comments

问题出现的原因是在结构体模型中更改值的方法不正确,导致无法实时更新布尔值的图标。

解决方法是使用更合适的方法来更改结构体模型中的值,并解决实时更新图标的问题。

以下是一个修复问题的解决方案:

func saveCardMinus(currentCard: CardModel) {

var index = currentCard.id - 1

cardsModelArray[index].saved.toggle()

}

但是,我确信整个解决方案都是不好的。正确/更合适的解决方法是什么?

(顺便说一句,现在我面临另一个问题:布尔值的图标更新不是实时的,您需要再次打开该卡片才能看到新值(填充的心形/未填充的心形))

0
0 Comments

问题的原因:

问题出现的原因是结构体(struct)中的属性值无法被更改,导致无法更新选中卡片的状态。

解决方法:

为了解决这个问题,可以使用Binding来传递选中的卡片。但是由于存在多个不良实践,我对整个代码进行了重构。

重构后的代码如下:

struct StackOverFlow: View {

@State private var currentCardIndex: Int?

@State private var cards: [CardModel] = []

var body: some View {

VStack {

if let index = currentCardIndex {

CardViewStackOver(card: $cards[index])

}

Button("Show random card") {

currentCardIndex = (0..

}

Button("Save / delete item") {

if let index = currentCardIndex {

cards[index].saved.toggle()

}

}

}

.onAppear {

if cards.isEmpty {

cards = load("LetsTalkTopics.json")

}

}

}

}

struct CardViewStackOver: View {

@Binding var card: CardModel

var body: some View {

VStack {

Text(card.topic)

Text(card.category)

Text(String(card.id))

HStack {

Image(systemName: card.saved ? "heart.fill" : "heart")

.font(.title)

.padding(15)

.padding(.bottom, 20)

.onTapGesture {

card.saved.toggle()

}

}

}

}

}

经过重构后,我们使用了`@State`来包装`currentCardIndex`和`cards`属性,使它们具有状态管理的能力。同时,在`CardViewStackOver`结构体中,我们使用了`@Binding`来传递选中的卡片,以便能够更改其状态。

这样,我们就解决了原始代码中无法更改结构体属性值的问题,并且通过重构代码,消除了一些不良实践。

0