在SwiftUI中使用函数初始化属性吗?

时间:2020-11-12 01:01:08

标签: swift struct swiftui

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

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

我想用每个位置的随机数而不是allVals变量的硬编码数字开始视图。看来我应该可以通过运行相同的pickThree()刷新功能来做到这一点……也许可以通过将其预先设置为allVals变量的值来实现:

@State var allVals = pickThree()

这会产生错误:

不能在属性初始化程序中使用实例成员'pickThree';属性初始化程序在“自我”可用之前运行

我在这里想念什么?

import SwiftUI

struct ThreeCards: View {
    // @State var allVals = pickThree() // PRODUCES ERROR
    @State var allVals = [1,2,3]
    
    var body: some View {
        VStack {
            HStack {
                Text(String(allVals[0]))
                Text(String(allVals[1]))
                Text(String(allVals[2]))
            }
            
            Button(action: {
                pickThree()
            }) {
                Text("Refresh")
            }
        }
    }
    
    func pickThree() -> [Int] {
        let one = Int.random(in: 1...3)
        let two = Int.random(in: 1...3)
        let three = Int.random(in: 1...3)
        
        allVals = [one, two, three]
        
        return allVals
    }
}

  

1 个答案:

答案 0 :(得分:1)

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

有几种方法。

  1. 改为使用静态函数:

当您不需要访问其他实例变量时适用。

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]
    }
}
  1. 初始化init中的实例变量:
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]
    }
}
  1. 出于这个特定目的,它更整洁:
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")
            }
        }
    }
}