iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Mobile Development

使用 SwiftUI 讓有趣的點子變成 Apps系列 第 22

D22 - 使用 SwiftUI 讓有趣的點子變成 Apps{無限猴子打字機: 讓猴子開始敲鍵盤}

  • 分享至 

  • xImage
  •  

前一天,完成打字的「猴子」,不過還沒有讓猴子開始打字的能力,這時候,又輪到 Timer 上場了。

再來看一次 UI

https://ithelp.ithome.com.tw/upload/images/20220922/20140622TZI99MJYaG.png

需求分析

  • 中間有兩個按扭
  • 按下「叫猴子開始打字囉」,開始發動 timer
  • 按下「叫猴子停手」,停下 timer

發動 timer 和停下 timer 的程式碼如下


/// 猴子開始打字囉
  private func askMonkeysTyping() {
    
    typingTimer = Timer.publish(every: 0.1, on: .main, in: .common)
      .autoconnect()
      .sink { _ in
        // TODO: 比對打字的邏輯之後處理
      }
  }
  /// 叫猴子停手
  private func stopMonkeysTyping() {
    
    typingTimer?.cancel()
  }

接下來,在 Button 裡面發動這些 func 就完成囉,整個程式碼如下

import SwiftUI
import Combine

struct InfiniteMonkeyTypingContentView: View {
  
  @State private var targetText = ""
  
  @State private var monkeyTyperCount = 1
  
  @State private var logText = ""
  
  @State private var textStyle = UIFont.TextStyle.body
  /// 發動「猴子」打字的 timer
  @State private var typingTimer: AnyCancellable?
  
  private var targetHint: String {
    if targetText.isEmpty {
      return "目前沒目標,請輸入目標文字在輸入框"
    }
    return "你的目標為: \(targetText)"
  }
  
  var body: some View {
    
    VStack {
      Text("無限猴子打字機")
        .font(.largeTitle)
        .padding(.top, 20)
      
      Text(targetHint)
        .lineLimit(1)
        .padding()
      
      TextField("請輸入目標", text: $targetText)
        .autocapitalization(.none)
        .padding()
        .textFieldStyle(.roundedBorder)
      
      monkeyTyperStepper
      
      monkeyActionButtons
      
      monkeyLogsAndClearLogs
      
      Rectangle()
        .foregroundColor(.white)
        .border(Color.blue)
        .padding()
      Spacer()
    }
  }
  
  private var monkeyTyperStepper: some View {
    HStack {
      Stepper("猴子數: \(monkeyTyperCount)") {
        stepperIncrease()
      } onDecrement: {
        stepperDecrease()
      }
    }
    .padding()
  }
  
  private var monkeyActionButtons: some View {
    HStack {
      Button("猴子停手") {
        stopMonkeysTyping()
      }
      
      Button("叫猴子開始打字囉") {
        askMonkeysTyping()
      }
    }
    .buttonStyle(.bordered)
    .padding()
  }
  
  private var monkeyLogsAndClearLogs: some View {
    HStack {
      Spacer()
      Text("猴子的打字紀錄")
      Button {
        // TODO: - 清掉打字
      } label: {
        Text("清除打字紀錄")
      }
      .padding(.leading, 20)
      .buttonStyle(.bordered)
      Spacer()
    }
  }
  
  private func stepperIncrease() {
    monkeyTyperCount += 1
  }
  
  private func stepperDecrease() {
    if monkeyTyperCount > 1 {
      monkeyTyperCount -= 1
    }
  }
  /// 猴子開始打字囉
  private func askMonkeysTyping() {
    
    typingTimer = Timer.publish(every: 0.1, on: .main, in: .common)
      .autoconnect()
      .sink { _ in
				let typedCharacter = createRandomString()
        print("發動產生文字: \(typedCharacter)")
        // TODO: 比對打字的邏輯之後處理
      }
  }
  /// 叫猴子停手
  private func stopMonkeysTyping() {
    
    typingTimer?.cancel()
  }
}

extension InfiniteMonkeyTypingContentView {
  
  private var alphabet: [String] {
    let characters = "abcdefghijklmnopqrstuvwxyz"
    var chars: [String] = []
    for char in characters {
      chars.append(String(char))
    }
    return chars
  }
  
  private func createRandomString() -> String {
    
    var resultString = ""
    
    for _ in 0..<monkeyTyperCount {
      resultString += alphabet.randomElement() ?? ""
    }
    return resultString
  }
}

試著發動一下,你在 console 就會看到「猴子」打出來的字

https://ithelp.ithome.com.tw/upload/images/20220922/20140622VhD0bhw4Zy.png


上一篇
D21 - 使用 SwiftUI 讓有趣的點子變成 Apps{無限猴子打字機: 做出猴子}
下一篇
D23 - 使用 SwiftUI 讓有趣的點子變成 Apps{無限猴子打字機: 打字紀錄}
系列文
使用 SwiftUI 讓有趣的點子變成 Apps30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言