目的
今天搭建一個數(shù)字選擇游戲,根據(jù)提示選擇對應(yīng)數(shù)字,選擇對則加分,否則減分。
開始
直接上代碼,具體代碼含義請看注釋,這種方式應(yīng)該比看文字方便快捷。
1.搭建出數(shù)字選擇內(nèi)容
/// 使用導(dǎo)航欄
NavigationView {
/// 使用垂直堆疊視圖
VStack {
/// 遍歷0-2,識別id為自身
ForEach(0...2, id: \.self) {
/// 往VStack上面添加圖片
Image(systemName: self.numbers[$0])
/// 設(shè)置圖片可變化尺寸
.resizable()
/// 設(shè)置圖片大小
.frame(width: 100, height: 100)
/// 設(shè)置圖片邊框及其顏色
.border(Color.black, width: 1)
}
}
}
效果:

image.png
2.添加導(dǎo)航欄標(biāo)題,內(nèi)容為需要點擊的數(shù)字
struct ContentView: View {
...
/// 設(shè)置需要點擊的圖片序號
var selecte = Int.random(in: 0...2)
var body: some View {
/// 使用導(dǎo)航欄
NavigationView {
/// 使用垂直堆疊視圖
VStack {
...
}
/// 設(shè)置標(biāo)題
.navigationBarTitle(Text("請點擊:" + numbers[selecte].prefix(1)))
}
}
}
效果:

image.png
3.添加圖片點擊事件
struct ContentView: View {
...
var body: some View {
...
/// 往VStack上面添加圖片
Image(systemName: self.numbers[num])
...
/// 添加點擊事件處理
.onTapGesture {
self.imageTap(tag: num)
}
...
}
}
/// 點擊了會調(diào)用該方法
func imageTap(tag: Int) {
print("點擊了\(tag)")
}
}
4.添加得分
struct ContentView: View {
...
/// 設(shè)置得分
@State var score = 0
...
/// 點擊了會調(diào)用該方法
func imageTap(tag: Int) {
print("點擊了\(tag)")
if tag == selecte {
score += 1
} else {
score -= 1
}
print("得分\(score)")
}
}
5.彈出和隱藏Alert
struct ContentView: View {
...
/// Alert的顯示與隱藏
@State var isAlertShow = false
/// Alert顯示的內(nèi)容
@State var alertTitle = ""
var body: some View {
...
/// 設(shè)置標(biāo)題
.navigationBarTitle(Text("請點擊:" + numbers[selecte].prefix(1)))
/// 設(shè)置alert
.alert(isPresented: $isAlertShow) { () -> Alert in
Alert(title: Text(alertTitle), message: Text("總分:\(score)"), dismissButton: .default(Text("繼續(xù)"), action: {
}))
}
}
}
/// 點擊了會調(diào)用該方法
func imageTap(tag: Int) {
print("點擊了\(tag)")
if tag == selecte {
score += 1
alertTitle = "點對了"
} else {
score -= 1
alertTitle = "點錯了"
}
isAlertShow = true
print("得分\(score)")
}
}
運行:

image.png
6.刷新問題
給numbers和selecte增加state屬性裝飾器
struct ContentView: View {
/// 設(shè)置0-8圖片數(shù)組,打亂順序
@State var numbers = ["0.circle", "1.circle", "2.circle", "3.circle", "4.circle", "5.circle", "6.circle", "7.circle", "8.circle"].shuffled()
/// 設(shè)置需要點擊的圖片序號
@State var selecte = Int.random(in: 0...2)
...
Alert(title: Text(alertTitle), message: Text("總分:\(score)"), dismissButton: .default(Text("繼續(xù)"), action: {
self.newQuestion()
}))
}
}
}
...
/// 刷新選項
func newQuestion() {
numbers.shuffle()
selecte = Int.random(in: 0...2)
}
}
現(xiàn)在點擊繼續(xù),即可刷新下一個選項。
完整代碼
import SwiftUI
struct ContentView: View {
/// 設(shè)置0-8圖片數(shù)組,打亂順序
@State var numbers = ["0.circle", "1.circle", "2.circle", "3.circle", "4.circle", "5.circle", "6.circle", "7.circle", "8.circle"].shuffled()
/// 設(shè)置需要點擊的圖片序號
@State var selecte = Int.random(in: 0...2)
/// 設(shè)置得分
@State var score = 0
/// Alert的顯示與隱藏
@State var isAlertShow = false
/// Alert顯示的內(nèi)容
@State var alertTitle = ""
var body: some View {
/// 使用導(dǎo)航欄
NavigationView {
/// 使用垂直堆疊視圖
VStack {
/// 遍歷0-2,識別id為自身
ForEach(0...2, id: \.self) { num in
/// 往VStack上面添加圖片
Image(systemName: self.numbers[num])
/// 設(shè)置圖片可變化尺寸
.resizable()
/// 設(shè)置圖片大小
.frame(width: 100, height: 100)
/// 設(shè)置圖片邊框及其顏色
.border(Color.black, width: 1)
/// 添加點擊事件處理
.onTapGesture {
self.imageTap(tag: num)
}
}
}
/// 設(shè)置標(biāo)題
.navigationBarTitle(Text("請點擊:" + numbers[selecte].prefix(1)))
/// 設(shè)置alert
.alert(isPresented: $isAlertShow) { () -> Alert in
Alert(title: Text(alertTitle), message: Text("總分:\(score)"), dismissButton: .default(Text("繼續(xù)"), action: {
self.newQuestion()
}))
}
}
}
/// 點擊了會調(diào)用該方法
func imageTap(tag: Int) {
print("點擊了\(tag)")
if tag == selecte {
score += 1
alertTitle = "點對了"
} else {
score -= 1
alertTitle = "點錯了"
}
isAlertShow = true
print("得分\(score)")
}
/// 刷新選項
func newQuestion() {
numbers.shuffle()
selecte = Int.random(in: 0...2)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
總結(jié)
使用SwiftUI,我們需要拋棄掉以前使用UIKit時候的很多思維,比如UIKite里面要彈出Alert,我們需要手動present,但是在SwiftUI,由于是MVVM架構(gòu),界面都應(yīng)該由數(shù)據(jù)來控制,所以Alert的顯示與隱藏綁定到一個屬性,當(dāng)屬性值發(fā)生改變,則Alert自動顯示與隱藏。