#22 以生命靈數實現頁面間的資料傳遞

目的

練習兩種IBSegueAction的傳資料程式

  • 基本版
  • 定義 init,由參數設定 property

實現功能

  • 利用CAShapeLayer呈現動態視覺效果
  • 透過DatePicker選生日
  • 將生日傳遞到下一頁後計算出生命靈數

Storyboard

在Storyboard設置兩個view controller,第一個BirthdayViewController可以選取生日,點選計算生命靈數按鈕後,第二個ResultViewController會顯示生命靈數的資訊

資料傳遞

Date Picker

在BirthdayViewController新增UIDatePicker()

let datePicker = UIDatePicker()datePicker.frame = CGRect(x: mainPadding, y: 320, width: contentWidth, height: contentWidth)
datePicker.preferredDatePickerStyle = .inline
datePicker.datePickerMode = .date
datePicker.overrideUserInterfaceStyle = .dark
datePicker.tintColor = .cyan
view.addSubview(datePicker)

IBSegueAction

將在BirthdayViewController的計算生命靈數按鈕拉Segue到ResultViewController,並將此Segue拉成@IBSegueAction,接下有種種不同的寫法

基本版

  1. 宣告let controller為終點畫面ResultViewController()
  2. controller的birthday變數即為datePicker選擇的日期
  3. 返回controller
class BirthdayViewController: UIViewController {@IBSegueAction func showResult(_ coder: NSCoder, sender: Any?) -> ResultViewController? {        let controller = ResultViewController(coder: coder)
controller?.birthday = datePicker.date
return controller
}

在class ResultViewController宣告birthday,因為加上!可以不用初始化。

class ResultViewController: UIViewController {var birthday: Date!

init版本

先在Class ResultViewController將原本var birthday: Date的!移除,所以需要增加init(coder: NSCoder, birthday: Date)的初始化

class ResultViewController: UIViewController {
var birthday: Date
init?(coder: NSCoder, birthday: Date) {
self.birthday = birthday
super.init(coder: coder)
}

原ResultViewController()的宣告便可以自動產生memberwise initializer

class BirthdayViewController: UIViewController {@IBSegueAction func showResult(_ coder: NSCoder, sender: Any?) -> ResultViewController? {
ResultViewController(coder: coder, birthday: datePicker.date)

}

計算生命靈數

生命靈數資料的stuct

建立生命靈數的struct

struct DestinyNumber {
var number: Int
var numberMeaning: String
var pros: String
var cons: String
var descriptions: String
}

建立資料陣列

var destinyNumbers = [
DestinyNumber(number: 0, numberMeaning: "", pros: "", cons: "", descriptions: ""),
DestinyNumber(number: 1, numberMeaning: "開創", pros:"獨立、積極、創造、領導、能量,富創意與理解力,為人聰明,喜歡領導。", cons: "強勢、獨斷、浮躁、自私、懶散、吹牛,主觀意識強,我行我素,人際關係淡薄。", descriptions: """
1 熱愛獨立,不惜代價追求獨立,天生的領袖,充滿自動自發...

計算生命靈數的function

生命靈數的計算方式

  1. 將生日數字加總,如1999–01–01將等於30
  2. 總和超過9便要再加總一次,因此30等於3
  3. 3便為生命靈數
var number = 1func calculateLifeNumber(date: Date) -> Int {
let dateFormater = DateFormatter()
dateFormater.dateFormat = "yMd"
var numberString = dateFormater.string(from: date)
var sum = 0
repeat {
sum = 0
for character in numberString {
let number = Int(String(character))!
sum += number
}
numberString = "\(sum)"
}while sum > 9
return sum
}

顯示生命靈數分析結果的畫面更新function

func updateUI() {
birthdayLabel.text = birthday(date: birthday)
number = calculateLifeNumber(date: birthday)
numberImage.image = UIImage(systemName: "\(number).square")
numberMeaningLabel.text = destinyNumbers[number].numberMeaning
prosLabel.text = destinyNumbers[number].pros
consLabel.text = destinyNumbers[number].cons
descriptionText.text = destinyNumbers[number].descriptions
print(calculateLifeNumber(date: birthday))
}

--

--