[SwiftUI 100 天] allowsHitTesting()

921 阅读2分钟

译自 www.hackingwithswift.com/books/ios-s…

更多内容,欢迎关注公众号 「Swift花园」

喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀

allowsHitTesting()

SwiftUI 可以让我们通过设置 allowsHitTesting() 为 false 来禁用交互,在项目中我们可以用它来在倒计时消耗完时禁用卡片的轻扫操作。

在内层的 ZStack 里添加这个 modifier —— 显示卡片的那个 stack:

.allowsHitTesting(timeRemaining > 0)

只有在 timeRemaining 大于等于 1 时才可以接收拖拽手势。

如果你实际尝试过这个游戏,你可能会发现,当所有卡片都回答完时,定时器会滑到屏幕中央,继续计时。我们希望用户完成游戏时,定时器结束计时,显示用户花费的总时间,并且能够重置游戏,重新尝试。

这需要费一些思考,因为仅仅把 isActive 设置为 false 是不够的 —— 如果应用进入后台,又回到前台 isActive 将被重新激活,而此时已经没有卡片剩下了。

让我们拆解一下。首先,我们需要一个方法来重置应用,以便用户可以再次尝试,添加下面代码到 ContentView

func resetCards() {
    cards = [Card](repeating: Card.example, count: 10)
    timeRemaining = 100
    isActive = true
}

其次,我们需要个按钮来触发这个函数,并且只有在所有卡片都被移除之后才会显示。把它放在最内层的ZStack 后面, allowsHitTesting()modifier 下方:

if cards.isEmpty {
    Button("Start Again", action: resetCards)
        .padding()
        .background(Color.white)
        .foregroundColor(.black)
        .clipShape(Capsule())
}

现在我们有了可以重启定时器的代码,我们需要在最后一张卡片被移除时停止定时器 —— 并且确保应用在进入后台回到前台时仍然保持停止状态。

首先需要在 removeCard(at:) 方法最后添加下面代码:

if cards.isEmpty {
    isActive = false
}

其次我们要更新添加到 willEnterForegroundNotification 的函数,增加检查卡片数量的条件:

.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
    if self.cards.isEmpty == false {
        self.isActive = true
    }
}

完成!


我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~

Swift花园微信公众号