Swift-換功能不換圖片之馬告生態園區圖片分享
scroll view delegate — 分頁和圖片縮放
前言:
上一份作業馬告生態園區圖片分享完成後,Peter建議可以嘗試另一份作業練習分頁和圖片的縮放,所以在複習完上堂課內容後就開始著手,不得不說資質有限研究參考作品的語法花了我好多的時間!
這份作業主要是研究UIScrollViewDelegate protocol 的相關功能,實作的功能分別是利用page control的小圓點顯示目前在第幾頁&在scroll view上顯示能所放大小的圖片。
在Peter的網頁有提供相關的提示
首先,研究幾份學長姐的作業後,發現作業的解法會依據縮放的寫法在分頁部分會有所不同!
縮放解法:
- scroll view 包住許多scroll view分頁的解法
2. 在viewForZooming(in:)內有一個isKind(of:)判斷是的語法
其實就是Peter網頁下方兩個學長姐作品的差異,後者研究了很久無法了解語法的內容,但它可以直接接續上份作業直接製作,而第一種方式基本上需要打掉重練!
第二種解法(先挑軟柿子吃)
接續上份作業寫下去
Step1. 加入page control並設定Auto layout條件
page control需加在scroll control內,建議直接加從library拉到左方編輯區,直接加在畫面上會自動加到stack view內
Auto layout條件就看個人,我是設定水平置中,距下surface area 20
Step2. 拉IBOutlet
分別為
@IBOutlet var imageViewCollection: [UIImageView]!@IBOutlet weak var scrollControl: UIScrollView!@IBOutlet weak var pageControl: UIPageControl!@IBOutlet var viewOutlet: UIView!
Step3. 繼承UIScrollViewDelegate,並指定scroll view的delegate為self
忘記在class寫UIScrollViewDelegate系統會提醒你
此外,除了在viewDidLoad內寫上
scrollControl.delegate = self
會同時初始化一些值,分別為
pageControl.numberOfPages = 9pageControl.currentPage = 0
numberOfPages的值為顯示器總共需顯示的頁數
currentPage的值為當前頁數減1,故在一開始設定第一頁的值就為0
Step4. 完成分頁程式碼
在Peter網頁中有提示
定義 UIScrollViewDelegate 的 scrollViewDidEndDecelerating(_:),它將在滑動停止在某分頁時呼叫,可在其中判斷目前所在的分頁。
程式碼如下
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {let currentPage = Int(scrollControl.contentOffset.x / scrollControl.frame.size.width)pageControl.currentPage = currentPage}
contentOffest是指scroll view原點從起始頁面滾動到的頁面的點,回傳的值為座標(建議直接看原文)
contentOffset.x則是取得x方向座標的值
scrollControl.frame.size.width則是取得scroll view的寬度
currentPage是藉由x方向座標值除以每頁scroll view的寬度,以獲得目前頁面,得到的值為CGFloat,故需轉為Int
Step5. 完成縮放程式碼
在Peter網頁分別有提示
“從 scroll view 的 Zoom 設定放大縮小的比例 “
以及
“定義 UIScrollViewDelegate 的 viewForZooming(in:),它將回傳使用者操作縮放手勢時被縮放的 view “
比例部分,點選scroll view後在Attributes Inspector的zoom設定,此次我是設定最大值為5,最小值為1
程式碼部份如下
func viewForZooming(in scrollView: UIScrollView) -> UIView? {for viewOutlet in scrollControl.subviews {if viewOutlet.isKind(of: UIView.self) {return viewOutlet}}return nil}
這部分的語法目前尚無法了解,歡迎高手替我解惑!
最後成品
測試縮放方式為按著option就可操作
GitHub部分,此次練習一開始都是重新開個project順便練習之前的操作!
第一種解法
在Peter文章中的提示有提到
“利用 scroll view 做分頁,然後在 scroll view 裡的每個分頁也是 scroll view,分頁裡的 scroll view 負責圖片的縮放 “
理解上與後來詢問Peter的答案大致相同,就是
scroll view包著stack view,stack view包著個分頁組成的scroll views,每個分頁的scroll view內含有一個image view
但在分頁裡圖片的設定一直搞不定,最後在Peter協助下才解決!
Step1. 完成分頁
操作重點如上方文字所敘述,在分頁部分仍可參考Peter先前的教學網頁
在其步驟4加入圖片步驟改為加入各含有image view的scroll view
在步驟6設定image view與scroll view設定Equal widths部分改為分頁的scroll view與最外層的scoll view設定Equal widths
然而,image view與分頁scroll view的Auto Layout條件設定最難搞定,要將image view設定與分頁scroll view相同的大小,詢問Peter後答案是需image view分別與分頁的content layout & frame layout設定間距為0
依據Peter某篇文章教學提到
content layout是設定scroll view能捲動的範圍大小
frame layout是設定scroll view本身的大小
此外,無聊亂try也發現另一種方式可達到同樣效果,image view設定水平與垂直置中,並將image view與分頁scroll view設定上下左右間距為0,此法也可計算出分頁scroll view內容的大小
Step2. 加入page control並設定Auto layout條件
同第二種解法
Step3.拉Outlet
分別為
@IBOutlet weak var pageControl: UIPageControl!@IBOutlet var scrollViewColection: [UIScrollView]!@IBOutlet var imageColection: [UIImageView]!@IBOutlet weak var mainScroll: UIScrollView!
Step4. 繼承UIScrollViewDelegate,並指定scroll view的delegate為self
指定scroll view的delegate為self是指分頁部分,利用for in語法完成
其餘部分與第二種解法相同
程式碼如下
override func viewDidLoad() {super.viewDidLoad()// Do any additional setup after loading the view.pageControl.numberOfPages = 9pageControl.currentPage = 0for scrollView in scrollViewColection {scrollView.delegate = self}
mainScroll.delegate = self}
Step5. 完成縮放程式碼
首先,在縮放部分可以選則在分頁storyboard各自設定縮放比例
或利用語法寫在for in迴圈中
super.viewDidLoad()// Do any additional setup after loading the view.pageControl.numberOfPages = 9pageControl.currentPage = 0for scrollView in scrollViewColection {scrollView.delegate = selfscrollView.maximumZoomScale = 5scrollView.minimumZoomScale = 1scrollView.zoomScale = 1}mainScroll.delegate = self}
而viewForZooming(in:)部分的程式碼就較為單純
func viewForZooming(in scrollView: UIScrollView) -> UIView? {return imageColection[pageControl.currentPage]}
最後成品
文章贅詞稍多,有些語法的解釋或觀念有錯誤敬請見諒!