gpt4 book ai didi

arrays - SwiftUI @State 数组不更新在 init() 期间附加的值

转载 作者:行者123 更新时间:2023-12-05 02:45:09 27 4
gpt4 key购买 nike

我是一名初级程序员,所以...

在 iMac Big Sur 11.2 上使用 Xcode 12.4 项目是“多平台应用程序”

我正在尝试构建一组要在网格中四处移动的图像。我将“My Image.png”复制到我的 Xcode 项目中并使用它很好,但无论我如何尝试将它放入数组中,它都会返回一个 nil 数组。我在另一台电脑上试过这个,它似乎有效。 Xcode 中的什么会影响这个? (或者我只是想象它在另一台机器上工作?:-p)

代码:

@State var stringURL: URL = Bundle.main.url(forResource: "My Image", withExtension: "png")!
Image(nsImage: NSImage(byReferencing: stringURL))

@State var arrayURLs = [URL]()
arrayURLs.append(Bundle.main.url(forResource: "My Image", withExtension: "png")!)
Image(nsImage: NSImage(byReferencing: arrayURLs[0]))

前 2 行有效,但最后 3 行在同一个应用程序中失败。我收到运行时错误“Index out of Range”,我认为这是因为 bundle 调用返回了 nil。

上下文基本相同。我在这个项目的最开始,从来没有超过第一行....

import SwiftUI

struct ContentView: View {
@State var pieceImageURLs = [URL]()


init() {
self.pieceImageURLs.append(Bundle.main.url(forResource: "Red Warrior", withExtension: "png")!)
}

var body: some View {
HStack {
Image(nsImage: NSImage(byReferencing: pieceImageURLs[0]))
}
}}



import SwiftUI

struct ContentView: View {
@State var stringURL: URL = Bundle.main.url(forResource: "My Image", withExtension: "png")!
@State var arrayURLs = [URL]()
init() {
stringURL = Bundle.main.url(forResource: "My Image", withExtension: "png")!
arrayURLs.append(Bundle.main.url(forResource: "My Image", withExtension: "png")!)
}

var body: some View {
HStack {
Image(nsImage: NSImage(byReferencing: stringURL))
Image(nsImage: NSImage(byReferencing: arrayURLs[0]))
}
Button(action: {
arrayURLs.append(Bundle.main.url(forResource: "My Image", withExtension: "png")!)
Image(nsImage: NSImage(byReferencing: arrayURLs[0]))
}) {
Text("add image")
}
}
}

'''

或者所有像这样的带有数组的图像行都失败了

最佳答案

这是一个有趣的行为,我自己也不会预测到这种行为。看起来 SwiftUI 真的不喜欢你在 View 的初始化阶段设置 @State 变量。有几种解决方法。

选项 1

你不能设置一个新值,但你可以在你的 init 中将它显式初始化为 State:

struct ContentView: View {
@State var pieceImageURLs = [URL]()

init() {
if let url = Bundle.main.url(forResource: "Frame 1-2", withExtension: "png") {
_pieceImageURLs = State(initialValue: [url]) // <--- Here
}
}

var body: some View {
HStack {
if let imgUrl = pieceImageURLs.first, let nsImage = NSImage(byReferencing: imgUrl) {
Image(nsImage: nsImage)
} else {
Text("HI")
}
}
.frame(minWidth: 300, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
}
}

选项 2

不要为此使用@State,因为它无论如何都是静态的(至少在您的示例中)——您只是在 init 中设置一个值。

struct ContentView: View {
var pieceImageURLs = [URL]() // <--- Here

init() {
if let url = Bundle.main.url(forResource: "Frame 1-2", withExtension: "png") {
pieceImageURLs.append(url)
}
}

var body: some View {
HStack {
if let imgUrl = pieceImageURLs.first, let nsImage = NSImage(byReferencing: imgUrl) {
Image(nsImage: nsImage)
} else {
Text("HI")
}
}
.frame(minWidth: 300, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
}
}

选项 3

使用状态,但在onAppear中设置:

struct ContentView: View {
@State var pieceImageURLs = [URL]()

var body: some View {
HStack {
if let imgUrl = pieceImageURLs.first, let nsImage = NSImage(byReferencing: imgUrl) {
Image(nsImage: nsImage)
} else {
Text("HI")
}
}
.onAppear { // <--- Here
if let url = Bundle.main.url(forResource: "Frame 1-2", withExtension: "png") {
pieceImageURLs.append(url)
}
}
.frame(minWidth: 300, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
}
}

选项 4

在 View 模型中执行初始化(ObservableObject)

class ViewModel : ObservableObject {  // <--- Here
@Published var pieceImageURLs = [URL]()

init() {
if let url = Bundle.main.url(forResource: "Frame 1-2", withExtension: "png") {
pieceImageURLs.append(url)
}
}
}

struct ContentView: View {
@ObservedObject var viewModel = ViewModel() // <--- Here

var body: some View {
HStack {
if let imgUrl = viewModel.pieceImageURLs.first, let nsImage = NSImage(byReferencing: imgUrl) {
Image(nsImage: nsImage)
} else {
Text("HI")
}
}
.frame(minWidth: 300, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
}
}

关于arrays - SwiftUI @State 数组不更新在 init() 期间附加的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66109828/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com