[Swift] 東京淺草觀音寺一百籤

上課的時候一聽到 random 就想到要做一個抽籤的 APP。

Demo
Outlet 拉法

https://gist.github.com/mmis1000/d94bb0a9f37cfd362453
上面這個連結是淺草寺的 .json 檔,但只抽一支籤卻要把其他 99 支籤都透過網路載回來,太浪費了,所以寫了一個 Google Apps Script(GAS),這個 GAS 會接收一個數字 number,回傳對應 ID 的籤詩,如果不帶數字,則會回傳隨機 ID 的籤詩,使用 GET Request 即可取得籤詩:

https://script.google.com/macros/s/AKfycbz_7GMhrxE0fzbiKDgkTtFPh0KiniMTZUz-Iepp0VeoMBTvp6EpmSmB-SYywLJPWfvbjQ/exec
https://script.google.com/macros/s/AKfycbz_7GMhrxE0fzbiKDgkTtFPh0KiniMTZUz-Iepp0VeoMBTvp6EpmSmB-SYywLJPWfvbjQ/exec?number=87

整個 APP 非常簡單,一個 Navigation Controller 跟一個 View Controller,View Controller 裡面放幾個 Label 跟一個 Table View。

按下返回鍵重設頁面:

@objc func resetState() {
imageView.image = originalImage
circularButton.isHidden = false
tableView.isHidden = true
imageView.alpha = 1.0
idLabel.text = ""
typeLabel.text = ""
poemLabel.text = ""
tableView.reloadData()
}

頁面初始化時設定 button style:

func makeButtonCircular() {
let minDimension = min(circularButton.frame.width, circularButton.frame.height)
circularButton.layer.cornerRadius = minDimension / 2
circularButton.layer.masksToBounds = true
}
func customizeButton() {
circularButton.setTitleColor(.white, for: .normal)
circularButton.setTitleColor(.gray, for: .highlighted)
circularButton.backgroundColor = .black
circularButton.alpha = 0.6
}

打 Google Apps Script,並傳入一個 1~100 的數字抽籤:

func fetchPoems(randomNumber: Int) {
guard let url = URL(string: "https://script.google.com/macros/s/AKfycbzgLMd3zq4epimJz2nV98oJ_UkE8W0EvgeBvvKdiqvzO5wXbQaKU3bYIAgM-_lgElSkcw/exec?number=\(randomNumber)") else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data, error == nil else {
print("Error fetching data: \(String(describing: error))")
return
}
do {
let decodedData = try JSONDecoder().decode(Poem.self, from: data)
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.poem = decodedData
self.resultEntries = decodedData.result
self.tableView.reloadData()
self.idLabel.text = decodedData.id
self.typeLabel.text = decodedData.type
self.poemLabel.text = decodedData.poem.replacingOccurrences(of: ",", with: "")
}
} catch {
print("Error decoding data: \(error)")
}
}
task.resume()
}

設定 TableViewCell 的內容,以及設定 Style 為 Right Detail,讓一個 Cell 中有兩個 Label,並且設定文字一個靠左對齊,一個靠右對齊:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resultEntries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "resultCell", for: indexPath)

cell.textLabel?.text = ""
cell.detailTextLabel?.text = ""

let key = Array(resultEntries.keys)[indexPath.row]
let value = resultEntries[key]

cell.textLabel?.text = key
cell.detailTextLabel?.text = value

cell.textLabel?.textAlignment = .left
cell.detailTextLabel?.textAlignment = .right

return cell
}

設定抽籤按鈕點擊後的動作:

@IBAction func drawButtonTapped(_ sender: UIButton) {
let blurEffect = UIBlurEffect(style: .systemMaterialDark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.view.addSubview(blurEffectView)

UIView.transition(with: self.view, duration: 3, options: [.transitionCrossDissolve], animations: {
self.imageView.image = self.newImage
self.circularButton.isHidden = true
self.imageView.alpha = 0.6
self.tableView.isHidden = false
self.fetchPoems(randomNumber: Int.random(in: 1...100))
}, completion: { _ in
UIView.animate(withDuration: 1, animations: {
blurEffectView.alpha = 0
}) { _ in
blurEffectView.removeFromSuperview()
}
})
}

GitHub:

Reference:

圖片產生:https://firefly.adobe.com/
淺草觀音寺一百籤資料來源:https://gist.github.com/mmis1000/d94bb0a9f37cfd362453

--

--