是否使用SwiftUI中的函数初始化属性?

是否使用SwiftUI中的函数初始化属性?,swift,struct,swiftui,Swift,Struct,Swiftui,我有一个简单的SwiftUI视图,其中显示三个数字位置和一个刷新按钮。刷新按钮运行一个picktree()函数,该函数用一个随机数字替换每个数字 为了启动视图,我需要给每个位置一个起始编号,如allVals变量所示 我希望在每个位置以随机数开始视图,而不是allVals变量中的硬编码数。似乎我应该能够通过运行相同的picktree()refresh函数来实现这一点……也许可以将其设置为allVals变量的值: @State var allVals=picktree() 这会产生一个错误: 无法

我有一个简单的SwiftUI视图,其中显示三个数字位置和一个刷新按钮。刷新按钮运行一个
picktree()
函数,该函数用一个随机数字替换每个数字

为了启动视图,我需要给每个位置一个起始编号,如
allVals
变量所示

我希望在每个位置以随机数开始视图,而不是
allVals
变量中的硬编码数。似乎我应该能够通过运行相同的
picktree()
refresh函数来实现这一点……也许可以将其设置为
allVals
变量的值:

@State var allVals=picktree()
这会产生一个错误:

无法在属性初始值设定项中使用实例成员“pickThree”;属性初始值设定项在“self”可用之前运行

我错过了什么

导入快捷界面
结构三卡:视图{
//@State var allVals=picktree()//产生错误
@状态变量allVals=[1,2,3]
var body:一些观点{
VStack{
HStack{
文本(字符串(allVals[0]))
文本(字符串(allVals[1]))
文本(字符串(allVals[2]))
}
按钮(操作:{
三
}) {
文本(“刷新”)
}
}
}
func picktree()->[Int]{
设1=Int.random(in:1…3)
设2=Int.random(in:1…3)
设三=Int.random(in:1…3)
allVals=[1,2,3]
返回所有值
}
}

语句
@State var allVals=picktree()
隐式要求
self
初始化实例变量
allVals
,但发生这种情况时,
self
尚不可用

有几种方法

  • 改用静态函数:
  • 这适用于不需要访问其他实例变量的情况

    struct ThreeCards: View {
        @State var allVals = ThreeCards.pickThree() 
        
        var body: some View {
            VStack {
                HStack {
                    Text(String(allVals[0]))
                    Text(String(allVals[1]))
                    Text(String(allVals[2]))
                }
                
                Button(action: {
                    allVals = ThreeCards.pickThree()
                }) {
                    Text("Refresh")
                }
            }
        }
        
        static func pickThree() -> [Int] {
            let one = Int.random(in: 1...3)
            let two = Int.random(in: 1...3)
            let three = Int.random(in: 1...3)
            return [one, two, three]
        }
    }
    
  • init
    中初始化实例变量:
  • 为了这个特殊的目的,要整洁得多:

  • 对你的第一个方法非常有效!您的第二个方法(我认为应该使用的方法)构建得很好,但当我在
    文本(String(allVals[0])
    行上的模拟器“Thread 1:Fatal error:Index out out range”中运行它时返回一个错误。有什么想法吗?@Sam哦,对不起。第二个仍然需要一些调整才能工作。我应该给
    allVals
    一个默认的int数组,以避免
    索引超出范围。有些重复。我为您的特定上下文想出了第三个选项。@BenjaminWen第三个选项既漂亮又简洁!我的头还在缠着这个快捷的东西。感谢您的见解。您可以将allVals初始化为空[int],然后在其中一个堆栈的右括号后调用.onAppear(),并在那里进行指令调用
    
    struct ThreeCards: View {
        @State var allVals = [Int.random(in: 1...3), Int.random(in: 1...3), Int.random(in: 1...3)]
        
        var body: some View {
            VStack {
                HStack {
                    Text(String(allVals[0]))
                    Text(String(allVals[1]))
                    Text(String(allVals[2]))
                }
                
                Button(action: {
                    allVals = pickThree()
                }) {
                    Text("Refresh")
                }
            }
        }
        
        init() {
            allVals = pickThree()
        }
        
        func pickThree() -> [Int] {
            let one = Int.random(in: 1...3)
            let two = Int.random(in: 1...3)
            let three = Int.random(in: 1...3)
            return [one, two, three]
        }
    }
    
    struct ThreeCards: View {
        @State var digits = ["1", "2", "3"].shuffled()
        
        var body: some View {
            VStack {
                HStack {
                    Text(digits[0])
                    Text(digits[1])
                    Text(digits[2])
                }
                
                Button(action: {
                    digits.shuffle()
                }) {
                    Text("Refresh")
                }
            }
        }
    }