如何在 Swift 中使用计时器切换布尔值

Posted

技术标签:

【中文标题】如何在 Swift 中使用计时器切换布尔值【英文标题】:How to toggle a boolean value using timer in Swift 【发布时间】:2020-12-02 11:05:32 【问题描述】:

我有一个名为“isMatched”的布尔值。它写在我的模型中。我使用这个布尔值来显示某个视图状态的视图。但是,我希望视图在 0.5 秒后自动隐藏。我尝试使用 DispatchQueue.main.asyncAfter 和 Timer,但总是收到错误“转义闭包捕获变异 'self' 参数”。我在下面复制了我的模型。请给我一个解决方案。

我在 'choose()' 函数中将布尔变量 'isMatched' 设为 true。

import Foundation

struct WordMatchingGameModel<CardContent> 
    private(set) var cards: Array<Card>
    private(set) var words: Array<Word>
    private(set) var gameDataSet: Array<String>
    private(set) var matchedWord: String = ""
    var isMatched: Bool = false
    private var colors: [[String]] = [["AeroBlue", "AeroBlue"], ["BlueBell", "BlueBell"], ["PinkLavender", "PinkLavender"], ["Opal", "Opal"], ["CornflowerBlue", "CornflowerBlue"]]

    mutating func choose(card: Card) 
        if let choosenIndex = cards.firstIndex(matching: card) 
            if !cards[choosenIndex].isTapped 
                cards[choosenIndex].isTapped = true
                cards[choosenIndex].bgColors = numberOfMatchedWords == 0 ? colors[0] : numberOfMatchedWords == 1 ? colors[1] : colors[2]
                words.append(Word(id: cards[choosenIndex].id, content: cards[choosenIndex].content))
                print(word)
                if match() 
                    for index in 0..<cards.count 
                        if cards[index].isTapped  cards[index].isDisabled = true 
                    
                    numberOfMatchedWords += 1
                    score += 10
                    matchedWord = word
                    isMatched = true
                    delay(interval: 0.5) 
                        self.isMatched = false
                    
                    words.removeAll()
                
             else 
                cards[choosenIndex].isTapped = false
                cards[choosenIndex].bgColors = ["GradientEnd", "GradientStart"]
                var tempWords = Array<Word>()
                
                for index in 0..<words.count 
                    if words[index].id != cards[choosenIndex].id  tempWords.append(words[index]) 
                
                words = tempWords
            
        
    
    
    func delay(interval: TimeInterval, closure: @escaping () -> Void) 
        DispatchQueue.main.asyncAfter(deadline: .now() + interval, execute: closure)
    
    
    func match() -> Bool 
        for index in 0..<gameDataSet.count 
            if gameDataSet[index] == word 
                return true
            
        
        return false
    
    var word: String 
        var array = Array<Character>()
        
        for index in 0..<words.count 
            array.append(words[index].content as! Character)
        
        return String(array).capitalized
    
    private(set) var numberOfMatchedWords: Int = 0
    private(set) var score: Int = 0
    
    init(numberOfCards: Int, gameDataSet: Array<String>, cardContentFactory: (Int) -> CardContent) 
        cards = Array<Card>()
        words = Array<Word>()
        self.gameDataSet = gameDataSet
        for index in 0..<numberOfCards 
            let content = cardContentFactory(index)
            self.cards.append(Card(id: index + 1, content: content))
        
        cards.shuffle()
        colors.shuffle()
    
    
    struct Card: Identifiable 
        var id: Int
        var content: CardContent
        var bgColors: [String] = ["GradientEnd", "GradientStart"]
        var isTapped: Bool = false
        var isDisabled: Bool = false
    
    struct Word: Identifiable 
        var id: Int
        var content: CardContent
    

【问题讨论】:

对 WordMatchingGameModel 使用类而不是结构。 ***.com/questions/58327013/… 感谢 Ezaji。它现在工作正常。但是,将 struct 转换为 class 后,我的整个视图的响应速度非常慢。这是一个公认的问题吗? 可能是因为延迟?)我需要更多信息才能更有帮助) 【参考方案1】:

在函数内为 self 创建一个引用,并在延迟函数内使用 self 的那个瞬间。

   mutating func choose(card: Card) 
          var createReference = self
                    ....................
                    delay(interval: 0.5) 
                        createReference.isMatched = false
                    
  

【讨论】:

以上是关于如何在 Swift 中使用计时器切换布尔值的主要内容,如果未能解决你的问题,请参考以下文章

使用计时器切换布尔值?

UITableView Swift中带有布尔值的切换按钮

如何在 Swift 的完成处理程序中返回布尔值

iOS如何从解析Swift 4中获取值“布尔”

如何使用 Context 和 Hooks 切换布尔值?

SwiftUI - 如何切换核心数据中的所有布尔值