首先說一下:大家應(yīng)該都知道現(xiàn)在面試官太裝逼了。我認(rèn)識一位從360出來的人說:一個alloc你都要讓我轉(zhuǎn)成rutime.再成c函數(shù)盗迟,然后椇#空間惭蹂,葉子函數(shù)再去問匯編,太屎了割粮。
前陣子面試的時候也是如此盾碗,后來再問到一些蘋果官方提供的一些控件時卻居然一點都不知道。
比如有一個面試官問:一個業(yè)務(wù)上要求左右滑動時切換頁面舀瓢,怎么做廷雅?
我的回答是:左右滑動的模塊有幾個就寫幾個基于UIViewController的類,然后這些模塊由一個UIPageViewController去控制京髓。
我說了各種各樣的好處之后航缀,面試官還不以為意,說我用一個UIScrollView去控制不行嗎堰怨?設(shè)置他的frame就行了芥玉。
我曾經(jīng)在這篇文章說過時至今日使用frame的缺點太突出了,我個人不建議备图。另一方面灿巧,如此多的代碼寫在一個VC當(dāng)中,那么業(yè)務(wù)代碼耦合的就太厲害了揽涮。而且我也在這篇文章里說過蘋果在UIKit里出來一個Container的概念抠藕。
之后面試官又問:如果我要是在之后的需求當(dāng)中再加上上下滑動呢?類似抖音那種蒋困。
我的回答便是:使用UIPageViewController更容易實現(xiàn)盾似。效果如下:
鑒于Xcode自帶的"Debug view Hierarchy"不太好用,大家湊合著看這個效果雪标。
抖音的效果是:視頻列表頁可以上下滑動以切換視頻源零院,同時視頻列表往右滑動則到搜索頁,往左側(cè)滑動則到up主的用戶詳情頁村刨。
接下來我就說說我的思路(以Swift語言來實現(xiàn))门粪。
第一步:創(chuàng)建一個新工程,默認(rèn)rootVC是工程中的ViewController
第二步:基于UIViewController分別創(chuàng)建三個VC烹困,為SearchViewController(搜索頁),VideosViewController(視頻列表頁)和UserInfoViewController(up主的用戶信息頁)乾吻。如下圖:
第三步:在ViewController里創(chuàng)建UIPageViewController髓梅,并且實現(xiàn)切換三個模塊拟蜻。代碼如下:
override func viewDidLoad() {
super.viewDidLoad()
// 創(chuàng)建搜索頁,視頻列表頁和用戶詳情頁
let searchVC : SearchViewController = SearchViewController()
let videosVC : VideosViewController = VideosViewController()
let userInfoVC : UserInfoViewController = UserInfoViewController()
self.viewControllers = [searchVC, videosVC, userInfoVC]
// 創(chuàng)建UIPageViewController
let pageVC : UIPageViewController = UIPageViewController.init(transitionStyle: UIPageViewController.TransitionStyle.scroll, navigationOrientation: UIPageViewController.NavigationOrientation.horizontal, options: nil)
pageVC.setViewControllers([videosVC], direction: UIPageViewController.NavigationDirection.forward, animated: false, completion: nil)
pageVC.dataSource = self
pageVC.delegate = self
// 將pageVC添加到當(dāng)前VC
self.addChild(pageVC)
self.view.addSubview(pageVC.view)
pageVC.view.frame = self.view.bounds
pageVC.didMove(toParent: self)
}
// UIPageViewController必須的兩個代理方法枯饿,這兩個代理方法控制三個頁面的先后順序
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
var index : Int = self.viewControllers.index(of: viewController) ?? NSNotFound
if (index == 0) || (index == NSNotFound) {
return nil
}
index -= 1
return self.viewControllers[index]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
var index : Int = self.viewControllers.index(of: viewController) ?? NSNotFound
if (index == 0) || (index == NSNotFound) {
return nil
}
index += 1
if index >= self.viewControllers.count {
return nil
}
return self.viewControllers[index]
}
經(jīng)過以上三步就簡單的實現(xiàn)了三個頁面的左右切換酝锅。那么視頻列表的上下切換也是基于UIPageViewController的,步驟如下:
第四步:基于UIViewController創(chuàng)建一個VideoViewController奢方,這個類用來播放視頻
第五步:在VideosViewController(視頻列表頁)里創(chuàng)建UIPageViewController搔扁,實現(xiàn)上下滑動,而且是無限滑動蟋字。跟第三步類似稿蹲,但是參數(shù)設(shè)置不一樣。代碼如下:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.blue
// 當(dāng)前類的功能描述
let desLabel : UILabel = UILabel(frame: self.view.bounds)
desLabel.numberOfLines = 0
desLabel.textColor = UIColor.white
desLabel.textAlignment = NSTextAlignment.center
desLabel.text = "抖音視頻列表頁\n往右滑到搜索頁鹊奖,往左滑到用戶詳情頁\n上下滑切換視頻"
self.view.addSubview(desLabel)
// 創(chuàng)建 UIPageViewController
let pageVC : UIPageViewController = UIPageViewController.init(transitionStyle: UIPageViewController.TransitionStyle.scroll, navigationOrientation: UIPageViewController.NavigationOrientation.vertical, options: nil)
let videoVC : VideoViewController = VideoViewController()
videoVC.videoIndex = self.currentIndex
pageVC.setViewControllers([videoVC], direction: UIPageViewController.NavigationDirection.forward, animated: false, completion: nil)
pageVC.dataSource = self
pageVC.delegate = self
// 將pageVC添加到當(dāng)前VC
self.addChild(pageVC)
self.view.addSubview(pageVC.view)
pageVC.view.frame = self.view.bounds
pageVC.didMove(toParent: self)
}
// MARK: - UIPageViewControllerDataSource
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if self.currentIndex == 1 {
return nil;
}
let videoVC : VideoViewController = VideoViewController()
videoVC.videoIndex = self.currentIndex - 1
videoVC.view.backgroundColor = UIColor.white
return videoVC;
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let videoVC : VideoViewController = VideoViewController()
videoVC.videoIndex = self.currentIndex + 1
videoVC.view.backgroundColor = UIColor.white
return videoVC;
}
// MARK: - UIPageViewControllerDelegate
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
// 簡單的動畫效果
let videoController : VideoViewController = pageViewController.viewControllers?[0] as! VideoViewController
self.currentIndex = videoController.videoIndex!
UIView.animate(withDuration: 2.0) {
videoController.view.backgroundColor = UIColor.clear
}
}
效果圖如下:
此工程我已上傳到Github苛聘,你的star是我的動力。
最后打個廣告忠聚,個人第三方庫:
UDUserDefaultsModel:NSUserDefaults的改進(jìn)方案
YIIFMDB:直接操作Model進(jìn)行增刪改查设哗,數(shù)學(xué)運(yùn)算等,且sql語句易于管理