#51 防疫生鮮購物 App — UIStepper 和數字變字串

Rose
彼得潘的 Swift iOS / Flutter App 開發教室
20 min readJun 4, 2021

UIStepper 和將數字變成畫面上的文字。疫情期間不要出門人擠人,就用線上生鮮購物 APP 來採購生鮮雜貨,解決三餐所需吧!

功能:

  • 商品分類選單:Scroll View(前二個可切換)
  • 子選單:Scroll View
  • 購買物品可以加減數量,每樣最多買10項
  • 總計購買金額
  • 清除購物車
  • 利用 NumberFormatter 將數字變成金錢格式
  • 金額小數點後最多顯示幾位
  • String 轉 Float

建立子選單的 Scroll View

View 可以先拉出 Exit 之外方便編輯,完成後再從左邊列表選取 View,拉進 Scroll View

再把 X,Y 座標設為 0,0

如何方便編輯 Scroll View 裡的物件

以前做過 Scroll View 的APP,這裡再複習一次

Scroll View 裡的物件因為會超出畫面的長度很多,不方便拉線或排版,

因此要編輯的時候,從左邊的列表裡把View拉出到 Exit 之下,View 就會顯示在 View Controller 的上方。

編輯完成再從左邊把 View 拉往畫面裡的 Scroll View 裡,拉進去之後座標會是負的,把X,Y座標都設成 0,0 就可以看到正常出現了。

將 View 拉回 Scroll View 的操作動畫

不是從左邊列表拉往上面的 Scroll View,會拉不進去
而是要拉往右邊 storyboard 的 Scroll View 裡

商品物件拉 IBOutlet

購買數量、Stepper 加減按鈕、總金額 拉 IBOutlet

// 數量
@IBOutlet weak var appleQtyTextField: UILabel!
@IBOutlet weak var bananaQtyTextField: UILabel!
@IBOutlet weak var pepperQtyTextField: UILabel!
@IBOutlet weak var gingerQtyTextField: UILabel!
// 價格
@IBOutlet weak var applePriceTextField: UILabel!
@IBOutlet weak var bananaPriceTextField: UILabel!
@IBOutlet weak var pepperPriceTextField: UILabel!
@IBOutlet weak var gingerPriceTextField: UILabel!
// Stepper
@IBOutlet weak var appleStepper: UIStepper!
@IBOutlet weak var bananaStepper: UIStepper!
@IBOutlet weak var pepperStepper: UIStepper!
@IBOutlet weak var gingerStepper: UIStepper!

@IBOutlet weak var totalLabel: UILabel!

建立儲存數量的變數

var itemApple:Int = 0
var itemBanana:Int = 0
var itemPepper:Int = 0
var itemGinger:Int = 0

Stepper 數量增減拉同一個 IBAction

將 Stepper 上的數值傳入 QtyTextField 裡

@IBAction func changeQty(_ sender: UIStepper) {
itemApple = Int(appleStepper.value)
itemBanana = Int(bananaStepper.value)
itemPepper = Int(pepperStepper.value)
itemGinger = Int(gingerStepper.value)

appleQtyTextField.text = String(itemApple)
bananaQtyTextField.text = String(itemBanana)
pepperQtyTextField.text = String(itemPepper)
gingerQtyTextField.text = String(itemGinger)
}

viewDidLoad 設定商品訂價

override func viewDidLoad() {
super.viewDidLoad()
// 設定價格
applePriceTextField.text = "4.99"
bananaPriceTextField.text = "4.99"
pepperPriceTextField.text = "4.99"
gingerPriceTextField.text = "4.99"
}

計算金額的 function

(1) 利用 NumberFormatter 將數字變成金錢格式。

let formatter = NumberFormatter()
formatter.numberStyle = .currency
var moneyString = formatter.string(from: NSNumber(value: sum))

NumberFormatter 可以幫我們將數字變成特定的字串格式。

formatter.numberStyle = .currency

將 numberStyle 設為 .currency 可顯示金錢格式,讓字串包含金錢符號和逗號。

numberStyle 的型別是 enum 定義的 Style,定義了許多 case,可將數字表示成不同的格式。

var moneyString = formatter.string(from: NSNumber(value: money))

將數字以指定的格式轉成字串,由於 string(from:) 的參數 from 型別是 NSNumber,所以我們須以 NSNumber(value: money) 將 Int 型別的 money 變成 NSNumber。

(2)小數點後最多顯示幾位。

一般數字取小數後二位是使用

let sumString: String! = String(format: "%.2f", sum)

但這裡我們使用金錢專用的方式取小數方式

maximumFractionDigits 代表小數點後最多顯示幾位。設為 0 時表示金錢為整數,沒有小數點。

我們要取二位數所以是 = 2

formatter.maximumFractionDigits = 2
moneyString = formatter.string(from: NSNumber(value: sum))

(3)String 轉 Float

水果的金額是字串,要用來跟數量做運算時,必須轉成一樣的 Float

之後才能把他拿來做運算

let applePrice = Float(applePriceTextField.text!)!
let bananaPrice = Float(bananaPriceTextField.text!)!
let pepperPrice = Float(pepperPriceTextField.text!)!
let gingerPrice = Float(gingerPriceTextField.text!)!

計算 function

func calculate() {
// 字串轉數字
let applePrice = Float(applePriceTextField.text!)!
let bananaPrice = Float(bananaPriceTextField.text!)!
let pepperPrice = Float(pepperPriceTextField.text!)!
let gingerPrice = Float(gingerPriceTextField.text!)!

// 總計 金額*數量
let sum = applePrice * Float(itemApple) + bananaPrice * Float(itemBanana) + pepperPrice * Float(itemPepper) + gingerPrice * Float(itemGinger)

// 數字轉金錢格式
let formatter = NumberFormatter()
formatter.numberStyle = .currency
var moneyString = formatter.string(from: NSNumber(value: sum))

//小數後二位
formatter.maximumFractionDigits = 2
moneyString = formatter.string(from: NSNumber(value: sum))

totalLabel.text = "\(moneyString!)"
}

最後再把 calculate() 加入 changeQty() 裡

@IBAction func changeQty(_ sender: UIStepper) {
//略...
calculate()
}

總金額會自動出現 $符號,以及滿千之後會有逗點

為了測試把蘋果價格改為500了

清除購物車

將所有數值歸零

@IBAction func clearAll(_ sender: UIButton) {
appleStepper.value = 0
bananaStepper.value = 0
pepperStepper.value = 0
gingerStepper.value = 0

appleQtyTextField.text = "0"
bananaQtyTextField.text = "0"
pepperQtyTextField.text = "0"
gingerQtyTextField.text = "0"
totalLabel.text = "0"
}

增加商品分類

之前的種類只有製作水果,後來增加了飲料類的 Scroll View

完成畫面

水果與飲料二個分類是可以點選的

完整程式碼:

import UIKitclass ViewController: UIViewController {

// 數量
@IBOutlet weak var appleQtyTextField: UILabel!
@IBOutlet weak var bananaQtyTextField: UILabel!
@IBOutlet weak var pepperQtyTextField: UILabel!
@IBOutlet weak var gingerQtyTextField: UILabel!

@IBOutlet weak var cocaQtyTextField: UILabel!
@IBOutlet weak var dietQtyTextField: UILabel!
@IBOutlet weak var spriteQtyTextField: UILabel!
@IBOutlet weak var pepsiQtyTextField: UILabel!
@IBOutlet weak var appleJuiceQtyTextField: UILabel!

// 價格
@IBOutlet weak var applePriceTextField: UILabel!
@IBOutlet weak var bananaPriceTextField: UILabel!
@IBOutlet weak var pepperPriceTextField: UILabel!
@IBOutlet weak var gingerPriceTextField: UILabel!

@IBOutlet weak var cocaPriceTextField: UILabel!
@IBOutlet weak var dietPriceTextField: UILabel!
@IBOutlet weak var spritePriceTextField: UILabel!
@IBOutlet weak var pepsiPriceTextField: UILabel!
@IBOutlet weak var appleJuicePriceTextField: UILabel!

// Stepper
@IBOutlet weak var appleStepper: UIStepper!
@IBOutlet weak var bananaStepper: UIStepper!
@IBOutlet weak var pepperStepper: UIStepper!
@IBOutlet weak var gingerStepper: UIStepper!

@IBOutlet weak var cocaStepper: UIStepper!
@IBOutlet weak var dietStepper: UIStepper!
@IBOutlet weak var spriteStepper: UIStepper!
@IBOutlet weak var pepsiStepper: UIStepper!
@IBOutlet weak var appleJuiceStepper: UIStepper!

// 分類
@IBOutlet weak var typeTextField: UILabel!
@IBOutlet weak var fruitsBtn: UIButton!
@IBOutlet weak var beveragesBtn: UIButton!

@IBOutlet weak var bakeryBtn: UIButton!
@IBOutlet weak var fruitsScrollView: UIScrollView!
@IBOutlet weak var beveragesScrollView: UIScrollView!

@IBOutlet weak var totalLabel: UILabel!

var itemApple:Int = 0
var itemBanana:Int = 0
var itemPepper:Int = 0
var itemGinger:Int = 0

var itemCoca:Int = 0
var itemDiet:Int = 0
var itemSprite:Int = 0
var itemPepsi:Int = 0
var itemAppleJuice:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// 設定價格
applePriceTextField.text = "4.99"
bananaPriceTextField.text = "4.99"
pepperPriceTextField.text = "4.99"
gingerPriceTextField.text = "4.99"
cocaPriceTextField.text = "4.99"
dietPriceTextField.text = "1.99"
spritePriceTextField.text = "1.50"
pepsiPriceTextField.text = "4.99"
appleJuicePriceTextField.text = "15.99"

// 預設分類
fruitsScrollView.isHidden = false
beveragesScrollView.isHidden = true
typeTextField.text = "Frash Fruits & Vegetable"

}

@IBAction func changeQty(_ sender: UIStepper) {
//把Stepper數字顯示到Qty上
itemApple = Int(appleStepper.value)
itemBanana = Int(bananaStepper.value)
itemPepper = Int(pepperStepper.value)
itemGinger = Int(gingerStepper.value)

itemCoca = Int(cocaStepper.value)
itemDiet = Int(dietStepper.value)
itemSprite = Int(spriteStepper.value)
itemPepsi = Int(pepsiStepper.value)
itemAppleJuice = Int(appleJuiceStepper.value)

appleQtyTextField.text = String(itemApple)
bananaQtyTextField.text = String(itemBanana)
pepperQtyTextField.text = String(itemPepper)
gingerQtyTextField.text = String(itemGinger)

cocaQtyTextField.text = String(itemCoca)
dietQtyTextField.text = String(itemDiet)
spriteQtyTextField.text = String(itemSprite)
pepsiQtyTextField.text = String(itemPepsi)
appleJuiceQtyTextField.text = String(itemAppleJuice)

calculate()
}
// 刪除
@IBAction func clearAll(_ sender: UIButton) {
appleStepper.value = 0
bananaStepper.value = 0
pepperStepper.value = 0
gingerStepper.value = 0
cocaStepper.value = 0
dietStepper.value = 0
spriteStepper.value = 0
pepsiStepper.value = 0
appleJuiceStepper.value = 0

appleQtyTextField.text = "0"
bananaQtyTextField.text = "0"
pepperQtyTextField.text = "0"
gingerQtyTextField.text = "0"
cocaQtyTextField.text = "0"
dietQtyTextField.text = "0"
spriteQtyTextField.text = "0"
pepsiQtyTextField.text = "0"
appleJuiceQtyTextField.text = "0"

totalLabel.text = "0"
}

//顯示水果分類
@IBAction func showFruits(_ sender: UIButton) {
fruitsScrollView.isHidden = false
beveragesScrollView.isHidden = true
typeTextField.text = "Frash Fruits & Vegetable"
}
// 顯示飲料
@IBAction func showBeverages(_ sender: UIButton) {
fruitsScrollView.isHidden = true
beveragesScrollView.isHidden = false
typeTextField.text = "Beverages"
}



// 金額計算
func calculate() {
// 字串轉數字
let applePrice = Float(applePriceTextField.text!)!
let bananaPrice = Float(bananaPriceTextField.text!)!
let pepperPrice = Float(pepperPriceTextField.text!)!
let gingerPrice = Float(gingerPriceTextField.text!)!

let cocaPrice = Float(cocaPriceTextField.text!)!
let dietPrice = Float(dietPriceTextField.text!)!
let spritePrice = Float(spritePriceTextField.text!)!
let pepsiPrice = Float(pepsiPriceTextField.text!)!
let appleJuicePrice = Float(appleJuicePriceTextField.text!)!

// 總計 金額*數量
let sum = applePrice * Float(itemApple) + bananaPrice * Float(itemBanana) + pepperPrice * Float(itemPepper) + gingerPrice * Float(itemGinger) +
cocaPrice * Float(itemCoca) + dietPrice * Float(itemDiet) + spritePrice * Float(itemSprite) + pepsiPrice * Float(itemPepsi) + appleJuicePrice * Float(itemAppleJuice)
// 取小數第二位
//let sumString: String! = String(format: "%.2f", sum)
// totalLabel.text = sumString

// 數字轉金錢格式
let formatter = NumberFormatter()
formatter.numberStyle = .currency
let moneyString = formatter.string(from: NSNumber(value: sum))

totalLabel.text = "\(moneyString!)"
}
}

參考資料

--

--

Rose
彼得潘的 Swift iOS / Flutter App 開發教室

Coding & Design 一直在學習的路上,從未停止,一有空檔就會摸摸我的兔子🐰