#32 利用 page control,segmented control,button & gesture 更換兔子餐廳菜單

Rose
彼得潘的 Swift iOS / Flutter App 開發教室
12 min readApr 23, 2021

這個作業是個綜合驚喜包,集結了四個可以切換圖片的功能。

年年說她有選擇困難,幫她決定一下菜單吧

用下面列出的功能規劃製作一個兔子餐廳,餐廳提供五種新鮮水果餐,
但因為年年有選擇困難(🐰:我才沒有💢),所以就讓我們幫兔子點餐吧❤️

Storyborad 新增元件:

  • Page Control 小點點換頁
  • Segmented Control 換頁
  • Button 往前往後換頁
  • Swipe Gesture Recognizer 左右滑手勢
  • Image View 圖片菜單
  • 顯示文字的 Label 菜單名稱
  • TextView 顯示食物的營養

排版完成的畫面:

就讓我用我們家的兔子殿下「年年」來當APP代言人吧

定義四個常數陣列:

因為菜單有五個,使用陣列來存放各個元件1~5顯示的內容
食物圖片、食物名稱 Label、頁碼、食物的營養

找了好幾篇用陣列方式寫的,找到 Andeline 同學的作業,參考了陣列以及換頁的寫法

連結畫面與程式碼:

分別將各個物件拉 OutletAction 讓物件與程式碼產生連結

Outlet 的命名

outlet 的名字一般會用名詞,且以元件的型別結尾,比方 UILabel 元件會取名 scoreLabel,UISlider 元件會取名 ageSlider。

Action 的命名

action 的名字一般會用動詞, 說明此 function 做的事,比方按鈕點選觸發的 singleAnswerButtonPressed,滑動 slider 觸發的 ageSliderChanged 或 changeAge。

設定 Segmented Control及Page Control的function

  • 定義變數 num 用來儲存要顯示的圖片、文字等的陣列順序
var num:Int = 0
  • 用function定義要同步改變的內容:圖片、文字、頁數、Page Controll、Segmented Controll
func sync() {
foodImageView.image = UIImage(named: foodImage[num])
foodLabel.text = showFoodLabel[num]
pageLabel.text = showPageLabel[num]
pageDot.currentPage = num
segment.selectedSegmentIndex = num
effectTextView.text = effectText[num]
}
  • 使用 if else 寫出五種情況,以 Segmented Control 為例,Page Control 以此類推
@IBAction func segmentControl(_ sender: UISegmentedControl) {
num = sender.selectedSegmentIndex
if segment.selectedSegmentIndex == 0 {
num = 0
sync()
} else if segment.selectedSegmentIndex == 1 {
num = 1
sync()
} else if segment.selectedSegmentIndex == 2 {
num = 2
sync()
} else if segment.selectedSegmentIndex == 3 {
num = 3
sync()
} else {
num = 4
sync()
}
}

上一頁、下一頁按鈕:

@IBAction func nextBtn(_ sender: Any) {
num = num + 1
if num == 0 {
sync()
} else if num == 1 {
sync()
} else if num == 2 {
sync()
} else if num == 3 {
sync()
} else if num == 4 {
sync()
} else {
num = 0
sync()
}
}

Swipe Gesture Recognizer (左右滑手勢)

UIKit 提供了六種不同的手勢可供監聽,分別為 Tap 輕點、 Long Press 長按、 Swipe 滑動、 Pan 拖曳、 Pinch 縮放及Rotation 旋轉,我們可以為元件加上這些手勢的監聽,並執行觸發時的動作。這次用到的是 Swipe。

點選要滑動的imageView,勾選User Interaction Enabled

新增二個 Swipe Gesture 元件,拉往整個 storyboard

分別 設定二個 Swipe Gesture 元件的方向為 Left 跟 Right

將兩個Swipe Gesture Recognizer 連結到同一個IBAction,先拉 Left 那一條連結程式碼

產生程式碼

@IBAction func swipeChangePage(_ sender: UISwipeGestureRecognizer) {
}

再拉 swipe 的 Right 那條從右邊的點點拉線往回連結

@IBAction func swipeChangePage(_ sender: UISwipeGestureRecognizer) {
if sender.direction == .left {
num += 1
if num == 0 {
sync()
} else if num == 1 {
sync()
} else if num == 2 {
sync()
} else {
num = 0
sync()
}
} else if sender.direction == .right {
num -= 1
if num == 2 {
sync()
} else if num == 1 {
sync()
} else if num == 0 {
sync()
} else {
num = 2
sync()
}
}
}

設定 viewDidLoad 的畫面預先顯示的 Label 內容:

override func viewDidLoad() {
super.viewDidLoad()
foodImageView.layer.cornerRadius = 10
foodLabel.text = showFoodLabel[0]
pageLabel.text = showPageLabel[0]
effectTextView.text = effectText[0]
}

兔子餐廳操作動畫展示

完整程式碼:

import UIKitclass ViewController: UIViewController {
let foodImage = ["raspberries","carrot","banana","broccoli","apple"]
let showFoodLabel = ["現摘覆盆子","有機紅蘿蔔","美味香蕉","清脆花椰菜","香甜蘋果"]
let showPageLabel = ["1","2","3","4","5"]
let effectText = [
"含輮花酸、可增加皮膚亮澤,促進新陳代謝、抗發炎。 ",
"富含維生素B1、B2、C、D、E、K及葉酸、鈣、胡蘿蔔素、食物纖維,宜少吃。",
"提高免疫力、改善體質、幫助排泄、改善情緒,使皮膚光滑細緻。",
"豐富的鈣質與纖維更能防止骨質疏鬆、對抗便秘、痔瘡與糖尿病、防止感冒與細胞感染。",
"可以降低體內不好的膽固醇,是天然的整腸藥,能夠強健腸胃功能。"
]

var num:Int = 0
@IBOutlet weak var foodImageView: UIImageView!
@IBOutlet weak var pageDot: UIPageControl!
@IBOutlet weak var segment: UISegmentedControl!
@IBOutlet weak var foodLabel: UILabel!
@IBOutlet weak var pageLabel: UILabel!
@IBOutlet weak var effectTextView: UITextView!



override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
foodImageView.layer.cornerRadius = 10
foodLabel.text = showFoodLabel[0]
pageLabel.text = showPageLabel[0]
effectTextView.text = effectText[0]
}
// 同步修改
func sync() {
foodImageView.image = UIImage(named: foodImage[num])
foodLabel.text = showFoodLabel[num]
pageLabel.text = showPageLabel[num]
pageDot.currentPage = num
segment.selectedSegmentIndex = num
effectTextView.text = effectText[num]
}
// 點點 切頁
@IBAction func pageControl(_ sender: UIPageControl) {
num = sender.currentPage
if pageDot.currentPage == 0 {
num = 0
sync()
} else if pageDot.currentPage == 1 {
num = 1
sync()
} else if pageDot.currentPage == 2 {
num = 2
sync()
} else if pageDot.currentPage == 3 {
num = 3
sync()
} else {
num = 4
sync()
}
}
// segment 切頁
@IBAction func segmentControl(_ sender: UISegmentedControl) {
num = sender.selectedSegmentIndex
if segment.selectedSegmentIndex == 0 {
num = 0
sync()
} else if segment.selectedSegmentIndex == 1 {
num = 1
sync()
} else if segment.selectedSegmentIndex == 2 {
num = 2
sync()
} else if segment.selectedSegmentIndex == 3 {
num = 3
sync()
} else {
num = 4
sync()
}
}
// 箭頭按鈕切頁
@IBAction func PreviousBtn(_ sender: Any) {
num = num - 1
if num == 4 {
sync()
} else if num == 3 {
sync()
} else if num == 2 {
sync()
} else if num == 1 {
sync()
} else if num == 0 {
sync()
} else {
num = 4
sync()
}
}
@IBAction func nextBtn(_ sender: Any) {
num = num + 1
if num == 0 {
sync()
} else if num == 1 {
sync()
} else if num == 2 {
sync()
} else if num == 3 {
sync()
} else if num == 4 {
sync()
} else {
num = 0
sync()
}
}

// 手勢換頁
@IBAction func swipeChangePage(_ sender: UISwipeGestureRecognizer) {
if sender.direction == .left {
num += 1
if num == 0 {
sync()
} else if num == 1 {
sync()
} else if num == 2 {
sync()
} else if num == 3 {
sync()
} else if num == 4 {
sync()
} else {
num = 0
sync()
}
} else if sender.direction == .right {
num -= 1
if num == 4 {
sync()
} else if num == 3 {
sync()
} else if num == 2 {
sync()
} else if num == 1 {
sync()
} else if num == 0 {
sync()
} else {
num = 4
sync()
}
}
}
}

--

--

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

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