编辑代码

图形化显示函数
//函数2:图形化显示数组
func displayArrayGraph() {
    let  myView1 = self.view.viewWithTag(2001) as! UIImageView
    let  myView2 = self.view.viewWithTag(2002) as! UIImageView
    myView1.backgroundColor = .darkGray
    myView2.backgroundColor = .darkGray

    let h =  myView1.frame.size.height
    let w =  myView1.frame.size.width

    let padding : CGFloat = 5
    let margin : CGFloat = 10

    //计算每个格子的高度和宽度
    let grid_w = (w - margin * 2 - padding * CGFloat(cols-1)) / CGFloat(cols)
    let grid_h = (h - margin * 2 - padding * CGFloat(rows-1)) / CGFloat(roes)

    for i in 0..<rows {
        for j in 0..<cols {
            let x = margin + CGFloat(j) * (grid_w + padding)
            let y = margin + CGFloat(i)*(grid_h + padding)
            let rect = CGFloat(x: x, y:y, width: grid_w, height: grid_h)
            //在上面的TmageView中显示
            let fileNamel = ivl[i*cols+j]
            let imgl = UIImage(named: fileNamel)
            let imgViewl = UIImageView(frame: rect)
            imgViewl.image = imgl
            imgViewl.backgroundColor = .yellow
            myView1.addSubview(imgViewl)
            //在下面的ImageView中显示
            let fileName2 = iv2(i*cols+j)
            let img2 = UIImage(named: fileName2)
            let imgView2 = UIImageView(frame: rect)
            imgView2.image = img2
            imgView2.backgroundColor = .yellow
            myView2.addSubview(imgView2)
        }
    }
}
4.2.2基础功能
//函数3:图形化显示程序,支持Button
    func displayArrayGraphButon() {
        let myView1 = self.view.viewWithTag(2001) as! UIImageView
        let myView2 = self.view.viewWithTag(2002) as! UIImageView
        myView1.backgroundColor = .darkGray
        myView2.backgroundColor = .darkGray
        //支持view可以进行交互等操作
        myView1.isUserInteractionEnabled = true
        myView2.isUserInteractionEnabled = true

        let h = myView1.frame.size.height
        let w = myView2.frame.size.width

        let padding : CGFloat = 5
        let margin : CGFloat = 10

        //计算每个格子的高度和宽度
        let grid_w = (w - margin * 2 - padding * CGFloat(cols-l)) / CGFloat(cols)
        let grid_h = (h - margin * 2 - padding * CGFloat(rows-l)) / CGFloat(rows)

        for i in 0..<rows {
            for j in 0..<cols {
                let x = margin + CGFloat(j) * (grid_w + padding)
                let y = margin + CGFloat(i)*(grid_h + padding)
                let rect = CGFloat(x: x, y:y , width: grid_w, height: grid_h)
                //在上面的ImageView中显示
                let fileNamel = ivl(i*cols+j)
                let imgl = UIImage(named: fileName1)
                let btn1 = UIButton(frame: rect)
                btn1.setImage(imgl, for: normal)
                btn1.backgroundColor = .yellow
                //Button的tag设定为4000及以上
                btn1.tag = i*cols+j +4000
                btn1.addTarget(self, action: #selector(buttonCheck(_:)),for: .touchUpInside)
                myView1.addSubview(btn1)
                //在下面的ImageView中显示
                let fileName2 = iv2[i*cols+j]
                let img2 = UIImage(named: rect)
                let btn2 = UIButton(frame: rect)
                btn2.setImage(img2, for: normal)
                btn2.backgroundColor = .yellow
                //Button的tag设定为5000及以上
                btn2.tag = i*cols+j + 5000
                btn2.addTarget(self, action: #selector(buttonCheck(_:)),for: .touchUpInside)
                myView2.addSubview(btn2)
            }
        }
    }
3Button事件的响应函数
//函数4: 不同点的Button被单击后调用
@objc func buttonCheck(_ sender : UIButton) {
    let tipsLabel = self.view.viewWithTag(1001) as! UIlabel
    let tag = sender.tag
    if tag >= 5000 {
        let row = Int ((tag - 5000) / cols)
        let col = tag - 5000 - cols * row
        print("Bottom(\(row),\(rool)")
        tipsLabel.text = "Bottom(\row),\(col))"
    }
    else if tag >= 4000 {
        let row = Int ((tag - 4000) / cols)
        let col = tag - 4000 - cols * row
        print("Top(\(row),\(col))")
        tipsLabel.text = "Top(\(row),\(col))"
    }
    else {
        print("Button.tag=\(sender.tag)")
        tipsLabel.text = "Button.tag=\(sender.tag)"
    }
}
4相同干扰项函数
func distractorCreate(mount:Int){
    for _ in 0..<mount {
       let col = Int(arc4random()) % cols
       let row = Int(arc4random()) % rows

       cords.append((row,col))
       //从images提供的字符中选择一个
       let index = Int(arc4random()) % images.count
       //影响iv1和iv2这两个图形
       iv1[cols*row + col] = images[index]
       iv2[cols*row + col] = images[index]
    }
}
5新增数据定义
//数据定义开始--
//定义行数和列数
let rows = 8
let cols = 8
//定义上下两个图形数组
var ivl : Array<String> = []
var iv2 : Array<string> = []
 //定义上下相同的干扰项数组
var cords : Array<(Int,Int)> = []
//干扰项和不同项只能是小图形
let images : Array<String> = ["bird","bee","flower","mogu"]
//数据定义结束--
4.2.3 不同项函数
//函数6:生成不同项的随机位置和随机内容
func differenceCreate(mount:Int){
    for _ in 0..<mount {
       let col = Int(arc4random()) % cols
       let row = Int(arc4random()) % rows

       errorCords.append((row,col))
       //从images提供的字符中选择一个
       let index=Int(arc4random()) % images.count
       //选择上面图形,还是下面图形?
       let which = Int(arc4random()) % 2
       //影响iv1和iv2 这两个图形
       if which == 0 {
          iv1[cols*row + col] = images[index]
        }
        else {
          iv2[cols*row + col] = images[index]
        }
    }
}
3
//函数 7:不同点的 Button被单击后调用,支持音效
   @objc func buttonCheckMusic(_ sender : UIButton) {
       let tipsLabel = self.view.viewWithTag(1001) as !UILabel
       var tag = sender.tag 
       if tag >= 5000 {
           tag -= 5000else if tag >= 4000 {
            tag -= 4000
        }
        let row = Int (tag/cols)
        let col = tag - cols * row

        let result = errorCords.filter {
            $0 == (row,col)
        }
        if result.count >= 1 {
           let path = Bundle.main.path(forResource:"birdsound",ofType:"m4a")
           let url = URL(fileURLWithPath: path!)
           soundPlayer=try? AVAudioPlayer(contentsOf: url)
           soundPlayer.play()
           tipsLabel.text =" 不同找到: (\(row),\(col))"
        }
        else {
             let path = Bundle.main.path(forResource: "error", ofType:"m4a")
             let url = URL(fileURLWithPath: path!)
             soundPlayer=try? AVAudioPlayer(contentsOf: url)
             soundPlayer.piay()
             tipsLabel.text = "找错啦: (\(row),\(col)"
        }
    }
4
btn1.addTarget(self, action: #selector(buttonCheck(_:)), for: touchupInside)
btn2.addTarget(self, action: #selector(buttonCheck(_:)), for: touchUpInside)

btn1.addTarget(self, action: #selector(buttonCheckMusic(_:)),for: .touchUpInside) 
btn2.addTarget(self, action: #selector(buttonCheckMusic(_:)),for: .touchUpInside)
4.2.4
//游戏是否结束标记
var GameOver = false
//游戏开始时间戳
var beginTimestamp : Int = 0
//游戏限定时间,单位:秒 
let GamePeriod = 20
//游戏本次花费时间,单位:秒 
var TimeCost = 0
2
//函数8: 获得当前时间戳
    func getCurrentTimeStamp() -> Int {
         let now = Date()
         let timeInterval : TimeInterval = now.timeIntervalSince1970
         return Int(timeInterval)
    }

//函数9:定时器倒计时函数,显示当前消耗时间和倒计时
    func timeElapse() {
         Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) {
timer) in
              let timestamp = self.getCurrentTimeStamp()
              let pastPeriod = timestamp - self.beginTimestamp
              let countDown = self.GamePeriod - pastPeriod
              self.TimeCost = pastPeriod
              if countDown <= 0 || self.GameOver {
                  self.GameOver = true
                  let tipsLabel = self.view.viewWithTag(1001) as! UILabel tipsLabel
                  text = "游戏结束,共消耗时间\(self.TimeCost)秒"
                  timer.invalidate()
              }
              let tipsLabel = self.view.viewWithTag(1002) as! UILabel 
              DispatchQueue.main.async {
                   tipsLabel.text = "您消耗\(pastPerio d)秒,倒计时\(countDown)秒"
              }
        }
    }
3
//函数 10:不同点的 Button 被单击后调用,支持音效、计时、游戏结束
    @objc func buttonCheckMusicTimer(_ sender : UIButton) {
        if GameOver {return}
        let tipsLabel = self.view.viewWithTag(1001) as! UILabel
        var tag = sender.tag 
        if tag >= 5000 {
             tag -= 5000
        }
         else if tag >= 4000 {
              tag -= 4000
        }
        let row = Int (tag / cols) 
        let col = tag - cols * row

        let result = errorCords.filter {
            $0== (row,col)
        }
        let reserved = errorCords.filter {
            $0!=(row,col)
        }
        errorCords = reserved

        if result.count >= 1 {
            sender.backgroundColor = .red
            let path = Bundle.main.path(forResource: "birdsound",ofType: "m4a" 
            let url = URL(fileURLWithPath: path!)
            soundPlayer=try? AVAudioPlayer(contentsOf:url) 
            soundPlayer.play()
            tipsLabel.text = "不同找到: (\(row),\(col)),还剩\(errorcord
count)个"
         if errorCords.count <= 0 {
             GameOver=true
             tipsLabel.text = "任务完成,共花费时间\(self.TimeCost)秒"
        }
    }
    else {
         sender.backgroundColor = .brown
         let path = Bundle.main.path(forResource: "error", ofType:"m4a")
         let url = URL(fileURLWithPath: path!)
         soundPlayer=try? AVAudioPlayer(contentsOf: url) 
         soundPlayer.play()
         tipsLabel.text = "找错啦: (\(row),\(col))"
    }
}
4
btn1.addTarget(self, action: #selector(buttonCheckMusic(:)), for: .touchUpInside) 
btn2.addTarget(self, action: #selector(buttonCheckMusic( :)), for: .touchUpInside)

btn1.addTarget(self, action: #selector(buttonCheckMusicTimer( :)), for:. touchUpInside)
btn2.addTarget(self, action: #selector(buttonCheckMusicTimer(_:)), for:. touchUpInside)

//游戏结束标志
GameOver = false
//获取游戏开始时间并保存
beginTimestamp = getCurrentTimeStamp()
//倒计时
timeElapse()
//数组初始化 
initGame()
distractorCreate(mount: 5) 
differenceCreate(mount: 3) 
displayArrayGraphButton()
4.2.5
// 函数 11:图形化显示程序,支持 Button,支持提示功能

func displayArrayGraphButtonTips() ({}
   let myview1 = self.view.viewWithTag(200i) as! UIImagevi 
   let myView2 = self.view.viewwithTag(2002) as! UIImagevl 
   myView1.backgroundColor = .darkGray
   myView2.backgroundColor = .darkGray
   // 支持 View 可以进行交互等操作
   myView1.isUserInteractionEnabled = true
   myView2.isUserInteractionEnabled = true

   let h = myViewl.frame.size.height
   let w = myViewl.frame.size.width

   let padding : CGFloat = 5
   let margin : CGFloat = 10

   //计算每个格子的高度和宽度
   let grid_w = (w - margin * 2 - padding * CGFloat(cols-1)) / CGFloat
(cols)
   let grid_h = (h - margin * 2 - padding * CGFloat(rows-1)) / CGFloat
(rows)

   for i in 0..<rows {
       for j in ..<cols {
           let x = margin + CGFloat(j) * (grid_w + padding) 
           let y = margin + CGFloat(i)*(grid_h + padding)
           let rect = CGRect(x: x, y:y , width: grid_w, height: grid_h)

           //在上面的ImageView中显示
           let fileNamel = ivl[i*cols+j] 
           let tagl = i*cols+j + 5000
           addButton(view: myViewl, rect: rect,fileName: fileNamel,
tag: tagl)
           //在下面的 ImageView 中显示
           let fileName2 = iv2[i*cols+j] 
           let tag2 = i*cols+j + 4000
           addButton(view: myView2,rect:rect,fileName:fileName2,
tag: tag2)
       }
    }
}
// 函数 12:View 上面添加Button的函数,提示功能,用于减少代码数量
func addButton(view:UIView,rect:CGRect,fileName:String,tag:Int) {
    let img = UIImage(named:fileName) 
    let btn = UIButton(frame: rect) 
    btn.setImage(img,for:.normal)

    var mytag = tag 
    if mytag >= 5000 {
        mytag -= 5000
    }
    else if mytag >= 4000 {
             mytag-=4000
    }
    let row = Int (mytag /cols) 
    let col = mytag - cols * row

    let result = errorCords.filter {
        $0== (row,col)}
    if result.count >= 1 && TipsFlag {
        btn.backgroundColor = .blue
    }
     else{
         btn.backgroundColor = .yellow
         }
    btn.tag = tag
    btn.addTarget(self, action: #selector(buttonCheckMusicTimer(_:)),
for: .touchUpInside)
    view.addSubview(btn)
}
  @IBAction func onTips(_ sender : UIButton){
    TipsFlag = ITipsflag
    dlsplayArrayGraphButtonTips()
  }
  @IBAction func onBegin(_ sender : UiButton)(
//游戏结束标志
GameOver = false
//获取游戏开始时间并保存
beginTimestamp = getCurrentTimeStamp()
// 倒计时
timeElapse()
//数纽初始化
initGame()
distractorCreate(mount:5)
diferenceCreate(mount:3)
displayArrayGraphButtonTips()
}
2
//函数12:View上面添加Button 的函数,提示功能,用于减少代码数量
func addButton(view:UIView,rect:CGRect,fileName:String,tag:Int) {
    let img = UIImage(named: fileName)
    let bth = UIButton(frame: rect)
    bth.setImage(img, for: .normal)

    var mytag = tag
    if mytag >= 5000 {
        mytag -= 5000
    }
    else if mytag >= 4000 {
        mytag -= 4000
    }
    let row = Int (mytag / cols)
    let col = mytag - cols * row

    let result = errorCords.filter {
        $0 == (row,col)
    }

    if result.count >= 1 && TipsFlag {
        btn.backgroundColor = .blue
        btn.tag = tag1btn.addTarget(self,action: #selector(buttonCheckMusicTimer(_:)),for: touchUpInside)
        view.addSubview(btn)
    }

    let result1 = cords.filter {
        $0 == (row,col)
    }
    if resultl.count >= 1 {
        btn.tag = tag
        btn.addTarget(self, action: #selector(buttonCheckMusicTimer(_:)),for: .touchUpInside)
        view.addSubview(btn)
    }
}

//函数13:移除所有子控件
func removeAllSubviews(view:UIView) {
    if view.subviews.count>0 {
        view.subviews.forEach({$0.removeFromSuperview()})
    }
}

@IBAction func onTips(_ sender : UIButton) {
    TipsFlag = !TipsFlag
    displayArrayGraphButtonTisp()
}

@IBAction Func onBegin(_ sends : UIButton) {
    //游戏结束标志
    GameOver = false
    //获取游戏开始时间并保存
    beginTimestamp = getCurrenTimeStamp()
    //倒计时
    timeElapse()
    //数组初始化
    initGame()
    distractorCreate(mount: 10)
    differenceCreate(mount: 8)
    displarArrayGraphButtonTips()
}

@IBAction Func onNext(_ sends : UIButton) {
    GameOver = true
    TipsFlag = falas
    let myView1 = self.view.viewWithTag(2001) as! UIImageView
    let myView2 = self.view.viewWithTag(2002) as! UIImageView
    CurrentBackground += 1
    if CurrentBackground > 4 {
        CurrentBackground = 1
    }
    let image = UIImage(named: "back0\(CurrentBackground)")!
    myView1.image = image
    myView2.image = image
    removeAllSubViews(view: myView1)
    removeAllSubViews(view: myView2)
}

4.3
//
// ContentView.swift
// LoginSwiftUI
//
// Created by Zhifeng Chen on 2020/8/1.
// Copyright ⓒ 2020 zhifeng Chen. All rights reserved.
//
import SwiftUI

struct ContentView : View {

    @State var userName : String = ""
    @State var passWord : String = ""

    var body: some View {
        VStack {
            Text("欢迎使用找不同")
                .font(.title)
                .padding()
            Divider()
                .background(Color(.brown))
            Image(systemName:"person")
                .resizable()
                .frame(width: 150, height: 150)
                .cornerRadius(50)

            VStack {
                TextField("请输入用户名", text: $userName)
                  .padding()
                  .padding(.leading,10)
                  .background(Color(.lightGray))
                  .cornerRadius(15)
                TextField("请输入密码", text: $passWord)
                  .padding()
                  .padding(.leading,10)
                  .background(Color(.lightGray))
                  .cornerRadius(15)
            }
            .padding()

            Button(action: {
                print("被点击了...")
            }, label: {Text("登录")}) 
               .padding()

            Spacer()   
            
        }
    }
}

struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

//
// ContentView.swift
// LoginSwiftUI
//
// Created by Zhifeng Chen on 2020/8/1.
// Copyright @ 2020 zhifeng Chen. All rights reserved.
//

import SwiftUI

let lightGrayColor = Color(red:239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0,opacity: 1.0, blue:
244.0/255.0, opacity: 1.0)

struct Contentview : View {

    // 保存输入的用户名
    @State var userName : String = ""
   // 保存输入的密码
   @State var passWord : String = ""
   // 是否需要弹出Alert 窗口
   @State private var alertFlag : Bool = false
   // 弹出窗口里面的具体内容
   @State private var alertMsg : String = ""
   var  body: some View {
        VStack {
            Text("欢迎使用找不同")
                .font(.title) //字体大小为标题
                .padding() //四周间隔
            Divider()
                .background(Color(.brown)) //背景色为brown
            Image("back02") //图片back02.png
                .resizable() //允许改变图像尺寸
                .frame(width: 150, height: 150) //尺寸改为150*150
                .cornerRadius(150) //圆角半径50

            VStack {
                TextField("请输入用户名", text: $userName)
                    .padding() //四周默认间隔
                    .padding(.leading,10) //前方间隔10
                    .background(lightGrayColor) //背景色
                    .cornerRadius(15) //圆角半径15
                TextField("请输入密码", text: $passWord)
                    .padding() //四周默认间隔
                    .padding(.leading,10) //前方间隔10
                    .background(lightGrayColor) //背景色
                    .cornerRadius(15) //圆角半径15
            }
            .padding() //四周默认间隔

            Button(action: {
                if self.userName == "Zfchen" && self.passWord == "123" {
                    self.alertFlag = true
                    self.alertMsg = "登录成功"
                }
                else {
                    self.alertFlag = true
                    self.alertMsg = "登录失败"
                }
            }, label: {
                Text("登录")
                    .font(.headline)
                    .foregroundColor(.white)
                    .frame(width: 220, height: 60)
                    .background(Color.green)
                    .cornerRadius(15.0)
            })
            .padding()
            Spacer()
        }
        .alert(isPresented: $alertFlag) { () -> Alert in
             Alert(title: Text("登录提示"), message: Text(self.alertMsg), dismissButton: .default(Text("确定")))
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}