QHalfFaceMakeup
封裝彈出頁面,可跟隨手勢滑動消失
近來無事,就寫了個彈出頁面的控件玩,類似微信讀書中的講書播放頁面。動畫彈出頁面后可跟隨手勢下滑動消失,上效果(圖1是demo效果,圖2是項目中應用效果)。

demo_show.gif

user_show.gif
使用
使用超簡單的
let tbv = TableView(frame: self.view.frame, style: .plain)
let halfFace = QHalfFaceMakeup(self, tbv)
halfFace.adjustOS = 57
halfFace.show()
思路
控件主要由兩個部分組成: QHalfFaceMakeup 和 QHalfFaceMakeupVC 。
QHalfFaceMakeup 是最外層,暴露接口,負責初始化控件和彈出內容頁面。
重點:彈出頁面的操作這里采用模態(tài)推出頁面,并且 modalPresentationStyle = .overFullScreen 。
開始時的想法是:采用彈出 View 作為容器,經過嘗試不管是把 View 加載 viewController 上,還是加在 window 上都沒有達到我想要的效果,遂棄之。
class QHalfFaceMakeup: NSObject {
var superVC: UIViewController!
var faceView: UIView!
var halfFace: QHalfFaceMakeupVC!
init(_ vc: UIViewController, _ face: UIView) {
super.init()
superVC = vc
faceView = face
halfFace = QHalfFaceMakeupVC()
}
/// 調整face有軸坐標,default = 0(緊挨導航欄),負值往上反之向下
var adjustOS: CGFloat! = 0 {
didSet {
halfFace.adjustOS = adjustOS
}
}
func show() {
halfFace.modalPresentationStyle = .overFullScreen
superVC.present(halfFace, animated: false) {
self.halfFace.addFace(self.faceView)
self.halfFace.show()
}
}
func dismiss() {
halfFace.close()
}
}
QHalfFaceMakeupVC 是重點,是展示內容的容器,負責處理展示 View 的基礎樣式和布局、手勢交互等。
1.布局:view -> baseView -> (topView & faceView)
- view 是 QHalfFaceMakeupVC 自帶 view 位于最底層,添加有點擊手勢,點擊釋放頁面,顏色半透明。
- baseView 承載展示效果和其他(比如圓角之類),其添加有平移手勢,滑動平移消失效果由此承擔。
- topView 是頂部消失按鈕;faceView 是主要展示內容,由外部傳入,控件不處理任何業(yè)務代碼。
2.手勢處理,若傳入的是 scrollView 或其子類 必定會和 baseView 的平滑手勢沖突
// MARK: - 手勢處理
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
let className: AnyClass = gestureRecognizer.classForCoder
if touch.view != self.view {
if NSStringFromClass(className) == "UITapGestureRecognizer" {
return false
}
}
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if otherGestureRecognizer.view is UIScrollView {
if gestureRecognizer.state == .began && (otherGestureRecognizer.view as! UIScrollView).contentOffset.y <= 0 {
(otherGestureRecognizer.view as! UIScrollView).bounces = false
return true
}
(otherGestureRecognizer.view as! UIScrollView).bounces = true
}
return false
}
3.平滑消失操作
// MARK: - 滑動關閉頁面
@objc private func panClose(_ panGesture: UIPanGestureRecognizer) {
var top: CGFloat = 64
if screenHeight == 812 {
top = 88
}
let offsetY = panGesture.translation(in: panGesture.view).y
if offsetY >= 0 {
UIView.animate(withDuration: 0.13, animations: {
self.baseView.transform = CGAffineTransform(translationX: 0, y: -self.baseView.frame.size.height + top + offsetY)
})
}
if panGesture.state == .ended || panGesture.state == .failed || panGesture.state == .cancelled {
if offsetY >= (baseView.frame.size.height - top)/4 {
close()
} else {
show()
}
}
}
至此就不貼代碼,也沒人看。想追究的小伙伴可以點擊 QHalfFaceMakeup追查到底!