预览图如下:
文件一览
1.ViewController:启动页,包含了LeftViewController和MainViewController:UITabBarController
2.LeftViewController:抽屉的view
3.MainViewController:UITabBarController
4.ClickViewController:UITabBarController的子view
AppDelegate设置启动页
//启动页设置为ViewController
let leftVC = LeftViewController()
let mainVC = MainViewController()
let vc = ViewController(leftController: leftVC, mainController: mainVC)
window?.rootViewController = UINavigationController(rootViewController: vc)
window?.makeKeyAndVisible()
LeftViewController创建抽屉的view
override func viewDidLoad() {
super.viewDidLoad()
//宽度设置为275
self.view.frame = CGRect(x: 0, y: 0, width: 275, height: UIScreen.main.bounds.size.height)
self.view.backgroundColor = UIColor.lightGray
let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
btn.center = self.view.center
btn.setTitle("click", for: .normal)
self.view .addSubview(btn)
btn.addTarget(self, action: #selector(click), for: .touchUpInside)
}
ViewController
//用枚举来记录抽屉的开关状态
enum NowState {
case open
case close
}
//默认为close
var state = NowState.close
//重写init方法,把LeftViewController和MainViewController加进来
init(leftController : LeftViewController , mainController : MainViewController){
super.init(nibName: nil, bundle: nil)
self.leftViewController = leftController
self.mainViewController = mainController
view.addSubview(mainController.view)
view.addSubview(leftController.view)
addChildViewController(mainController)
addChildViewController(leftController)
}
//viewWillAppear里先把leftViewController移动到屏幕外
override func viewWillAppear(_ animated: Bool) {
leftViewController?.view.transform = CGAffineTransform(translationX: -275, y: 0)
}
"抽屉"按钮的单击响应方法
@objc func openLeftView(){
UIView.animate(withDuration: 0.7) {
if(self.state == NowState.close){
self.mainViewController?.view.transform = CGAffineTransform(translationX: 275, y: 0)
self.leftViewController?.view.transform = CGAffineTransform(translationX: 0, y: 0)
self.state = NowState.open
}else{
self.mainViewController?.view.transform = CGAffineTransform(translationX: 0, y: 0)
self.leftViewController?.view.transform = CGAffineTransform(translationX: -275, y: 0)
self.state = NowState.close
}
}
}
单击按钮后若为close状态则leftView和mainView都向右平移275并将状态改为open
单击按钮后若为open状态则leftView和mainView都向左平移275并将状态改为close
目前为止完成单击按钮弹出和恢复抽屉的功能
添加手势
override func viewDidLoad() {
super.viewDidLoad()
let gesture = UIPanGestureRecognizer(target: self, action: #selector(viewPan(sender:)))
self.mainViewController?.view.addGestureRecognizer(gesture)
}
@objc func viewPan(sender: UIPanGestureRecognizer) {
let x = sender.translation(in: self.mainViewController?.view).x
guard let frame = self.leftViewController?.view.frame,
let frame2 = self.mainViewController?.view.frame else{
return;
}
if(sender.state == UIGestureRecognizerState.changed){
//当为close状态时,不能向左滑动
if(self.state == NowState.close && x-275 >= -275){
mainViewController?.view.transform = CGAffineTransform(translationX: x, y: 0)
leftViewController?.view.transform = CGAffineTransform(translationX: x-275, y: 0)
print("x:\(x)--main:\(frame2.origin.x)--left:\(frame.origin.x)")
//当为open状态时,不能向右滑动
}else if(self.state == NowState.open && x+275 <= 275){
mainViewController?.view.transform = CGAffineTransform(translationX: x+275, y: 0)
leftViewController?.view.transform = CGAffineTransform(translationX: x, y: 0)
print("x:\(x)--main:\(frame2.origin.x)--left:\(frame.origin.x)")
}
}else if(sender.state == UIGestureRecognizerState.ended || sender.state == UIGestureRecognizerState.cancelled || sender.state == UIGestureRecognizerState.failed){
UIView.animate(withDuration: 0.7) {
//结束滑动的时候,根据结束时的位置来判断剩下的动画是打开还是关闭
if(frame2.origin.x >= 133)){
self.state = NowState.open
self.mainViewController?.view.transform = CGAffineTransform(translationX: 275, y: 0)
self.leftViewController?.view.transform = CGAffineTransform(translationX: 0, y: 0)
}else{
self.state = NowState.close
self.mainViewController?.view.transform = CGAffineTransform(translationX: 0, y: 0)
self.leftViewController?.view.transform = CGAffineTransform(translationX: -275, y: 0)
}
}
print("x:\(x)--main:\(frame2.origin.x)--left:\(frame.origin.x)")
}
}
以上就是滑动手势的代码
页面跳转
//如果时打开状态,先关闭然后跳转
@objc func clickPush(){
if(state == NowState.open){
UIView.animate(withDuration: 0.7, animations: {
if(self.state == NowState.close){
self.mainViewController?.view.transform = CGAffineTransform(translationX: 275, y: 0)
self.leftViewController?.view.transform = CGAffineTransform(translationX: 0, y: 0)
self.state = NowState.open
}else{
self.mainViewController?.view.transform = CGAffineTransform(translationX: 0, y: 0)
self.leftViewController?.view.transform = CGAffineTransform(translationX: -275, y: 0)
self.state = NowState.close
}
}, completion: { (stats) in
let vc = ClickViewController()
self.navigationController?.pushViewController(vc, animated: true)
})
}
}
以上就是主要代码的说明,详细代码可以看GitHub上的