SwiftUI-如何通过静态函数设置非静态变量

时间:2020-06-30 02:34:38

标签: swiftui

我目前正在跟随series of lectures from Stanford来学习Swift(代码来自第1-4课以及我要完成的家庭作业),并且在设置实例var(非静态)时遇到问题来自静态函数。我已经做到了这一点,但我希望它能够使游戏的不同实例具有不同的主题

class EmojiMemoryGame: ObservableObject {
    
    //Create the model in the viewController
    @Published private var cardGame = EmojiMemoryGame.createMemoryGame()
    
    static let themesArray = [
        theme(name: "Halloween", color: Color.orange, emojiArray: ["?","?","?","?","?","?","?"])
            {6},
        theme(name: "Aqua", color: Color.blue, emojiArray: ["?‍☠️","?","?","⚓️","?","?","⛵️","?","?","?"]) {Int.random(in: 5...7)},
        theme(name: "Animals", color: Color.gray, emojiArray: ["?","?","?","?","?","?","?","?"])
            {Int.random(in: 3...4)}
    ]
    
    static var selectedTheme: theme?
    
    //Public Static Function
    //Input: None
    //Output: MemoryGame<String> struct
    //Usage: Return the card game with emoijs inited
    static func createMemoryGame() -> MemoryGame<String> {
        
        //ISSUE
        //Want to get a random theme from the themes array and assign it to an instance of this class but get an error beceause the function is static
        selectedTheme = themesArray[Int.random(in: 0..<themesArray.count)]
        let emojisArray = selectedTheme!.emojiArray
        
        //Create the actual MemoryGame
        return MemoryGame<String>(numberOfPairsOfCards: selectedTheme!.numberOfCards(), cardContentFactory: { cardPairIndex in
            emojisArray[cardPairIndex]
        })
    }
    
    //Struct Theme
    struct theme {
        let name: String
        let color: Color
        let emojiArray: [String]
        let numberOfCards: () -> Int
    }

我希望能够从theme获得一个随机themesArray,但让selectedTheme为实例变量。谁能给我一些建议?

2 个答案:

答案 0 :(得分:2)

您无需将selectedTheme声明为静态。

您只需要添加一个初始化程序并更改创建您的记忆游戏的函数返回的内容即可。我删除了一些代码,以便于查看更改内容。

请注意,我们已将cardGame的设置删除到init。我们还从selectedTheme中删除了对createMemoryGame的所有引用。 createMemoryGame函数现在返回一个tuple,这意味着我们可以轻松访问它创建的游戏和主题。

class EmojiMemoryGame: ObservableObject {
    
    @Published private var cardGame: MemoryGame<String>

    var selectedTheme: Theme // structs and classes should have capital letters
    
    /// This now returns a tuple of the game we have created and the theme that we have chosen
    static func createMemoryGame() -> (MemoryGame<String>, Theme) {
        
        let theme = EmojiMemoryGame.themesArray[Int.random(in: 0..<themesArray.count)]
        let emojisArray = theme!.emojiArray 
        let game =  MemoryGame<String>(numberOfPairsOfCards: theme!.numberOfCards(), cardContentFactory: { cardPairIndex in
            emojisArray[cardPairIndex]
        })
        return (game, theme)
    }

    // We add an initialiser to our class so that all the values that we need are initialised
    init() {
        let (game, theme) = EmojiMemoryGame.createMemoryGame() // note that the use of the names game and theme are arbitrary. 
        self.cardGame = game
        self.selectedTheme = theme
    }
}

答案 1 :(得分:0)

就像让您的ThemesArray是一个静态变量一样。但是,您无需将selectedTheme声明为static。如您所说,它是一个实例变量。

声明selectedTheme如下:

var selectedTheme: theme?

然后按如下所示对其进行初始化:

selectedTheme = EmojiMemoryGame.themesArray[Int.random(in: 0..<EmojiMemoryGame.themesArray.count)]
let emojisArray = selectedTheme!.emojiArray