You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI实现按钮触发JSON随机文本刷新的问题

问题

我希望创建一个由按钮触发的、从JSON文件读取内容的随机文本生成器。目前已实现随机文本生成功能,但需返回其他视图再重新打开当前视图才能刷新内容。尝试通过函数实现按钮刷新功能,但每次都出现大量错误。

原代码

Quote模型与视图代码

struct Quote: Codable {
    var text: String
    var author: String
    
    var shareMessage: String {
        return "\"\(text)\" - \(author)"
    }
}

struct PytaniaNormalne : View {
    @State private var quote : Quote?
    var body: some View {
        VStack {
            if let quote = quote {
                VStack {
                    VStack {
                        Text(quote.text)
                            .font(.system(.title3))
                            .foregroundColor(.white)
                        Text(quote.author)
                            .font(.system(.title3))
                            .foregroundColor(.white)
                    }
                }.frame(width: 240)
                    .background(RoundedRectangle(cornerRadius: 7.0).fill(Color.blue))
            }
        }.onAppear {
            let quotes = Bundle.main.decode([Quote].self, from: "quotes.json")
            quote = quotes.randomElement()
        }
    }
}

JSON文件内容

[
    {
        "text": "Pytanie 1",
        "author": "tekst"
    },
    {
        "text": "Pytanie 2",
        "author": "tekst"
    },
    {
        "text": "Pytanie 3",
        "author": "teskt"
    },
    {
        "text": "Pytanie 4",
        "author": "tekst"
    },
    {
        "text": "Pytanie 5",
        "author": "author"
    },
    {
        "text": "Pytanie 6",
        "author": "author"
    },
    {
        "text": "Pytanie 7",
        "author": "author"
    }
]

解决方法

步骤1:提取刷新逻辑并优化JSON读取

把JSON文件读取逻辑移到视图初始化时完成(只需读取一次),同时定义独立的刷新函数来随机选择新的Quote:

struct PytaniaNormalne : View {
    @State private var quote : Quote?
    private let quotes: [Quote] // 存储所有读取到的Quote
    
    // 初始化时读取JSON文件
    init() {
        self.quotes = Bundle.main.decode([Quote].self, from: "quotes.json")
    }
    
    // 刷新随机Quote的函数
    private func refreshQuote() {
        quote = quotes.randomElement()
    }
    
    var body: some View {
        VStack(spacing: 20) { // 添加间距让布局更美观
            if let quote = quote {
                VStack(spacing: 10) {
                    Text(quote.text)
                        .font(.system(.title3))
                        .foregroundColor(.white)
                        .multilineTextAlignment(.center) // 文本居中
                    Text(quote.author)
                        .font(.system(.title3))
                        .foregroundColor(.white)
                        .multilineTextAlignment(.center)
                }
                .frame(width: 240, minHeight: 120) // 增加最小高度避免内容过短
                .padding()
                .background(RoundedRectangle(cornerRadius: 7.0).fill(Color.blue))
            }
            
            // 添加刷新按钮
            Button(action: refreshQuote) {
                Text("刷新")
                    .font(.title2)
                    .padding()
                    .background(Color.gray)
                    .foregroundColor(.white)
                    .cornerRadius(7)
            }
        }
        .onAppear {
            refreshQuote() // 视图出现时初始化第一个Quote
        }
    }
}

关键改动说明

  1. 初始化时读取JSON:将JSON读取放在init方法中,避免每次刷新都重复读取文件,提升性能。
  2. 独立刷新函数:refreshQuote函数负责从已读取的quotes数组中随机选择一个元素,并赋值给@State修饰的quote变量。由于@State会触发视图更新,修改后UI会自动刷新。
  3. 添加刷新按钮:通过Button的action参数调用refreshQuote函数,点击按钮即可触发刷新。
  4. 布局优化:增加了间距、文本居中、最小高度等调整,让界面更友好。

内容的提问来源于stack exchange,提问作者Wamakaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:15:58