ios:點選tabbar中間按鈕彈出選單(swift 3實現)
阿新 • • 發佈:2019-01-02
先上一張圖看看效果:
最近在自學swift3,就用swift3重寫了這個小demo,在專案開發中像這種彈出選單使用的機率還是很大的,在這裡僅僅做一個簡單的分享,本例子中沒有難度大高深的程式碼,純屬練練手,如有不嚴謹的地方,還請多多指正!
下面mark一下一些關鍵的程式碼:
ViewController.swift
//
// ViewController.swift
// SwiftDemo
//
// Created by turbomx on 2016/11/26.
// Copyright © 2016年 xiazy. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var footView: UIView!
@IBOutlet weak var popBtn: UIButton!
@IBAction func popBtnClicked(_ sender: Any) {
let bgImg :UIImage? = UIImage.imageWithCaptureView(view: self.view)
let popVC : MXPopMenuVC = MXPopMenuVC()
popVC.bgImg = bgImg
self .navigationController?.pushViewController(popVC, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "首頁"
let bgImgView :UIImageView = UIImageView(image: UIImage(named:"bg.png")!)
bgImgView.frame = UIScreen.main.bounds
self .view.insertSubview(bgImgView, belowSubview: self.footView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension UIImage{
//截圖
class func imageWithCaptureView(view:UIView)->UIImage?{
let size:CGSize = CGSize(width: view.bounds.size.width, height: view.bounds.size.height-40)
//開啟點陣圖上下文
UIGraphicsBeginImageContextWithOptions(size,false, 0)
//獲取上下文
let ctx :CGContext? = UIGraphicsGetCurrentContext()
//把控制元件的圖層渲染到上下文,layer只能渲染
view.layer .render(in: ctx!)
//生成新圖片
let image:UIImage? = UIGraphicsGetImageFromCurrentImageContext()
//關閉上下文
UIGraphicsEndImageContext()
return image;
}
}
MXPopMenuVC.swift
//
// MXPopMenuVC.swift
// SwiftDemo
//
// Created by turbomx on 2016/11/28.
// Copyright © 2016年 xiazy. All rights reserved.
//
import UIKit
class MXPopMenuVC : UIViewController{
var upIndex:Int = 0
var downIndex:Int = 0
var closeImgView:UIImageView?
var myTimer:Timer?
var bgImg:UIImage?
lazy var itemButtons :[MXMenuButton] = {
return []
}()
lazy var ary:Array<String> = {
var tempAry:Array<String> = []
for i in 18001...18006{
tempAry.append("\(i)")
}
return tempAry
}()
lazy var titleAry:[String]={
return ["學習","交流","關注","sina","圍脖:","turbomx"];
}()
//程式碼生成檢視
override func loadView() {
super.loadView()
self.navigationItem.setHidesBackButton(true, animated: false)
let contentView:UIView = UIView(frame: UIScreen.main.bounds)
contentView.backgroundColor = UIColor.white
let imgView:UIImageView = UIImageView(image: self.bgImg!)
//建立蒙板
let bgView:UIView = UIView(frame: UIScreen.main.bounds)
bgView.backgroundColor = UIColor(white: 0.9, alpha: 0.8)
imgView.addSubview(bgView)
contentView.addSubview(imgView)
self.view = contentView
}
override func viewDidLoad() {
super.viewDidLoad()
self.addMenu()
self.addCloseImg()
//設定定時器,彈出逐個彈出選單按鈕
self.myTimer = Timer(timeInterval: 0.1, target: self, selector: #selector(popupBtn), userInfo: nil, repeats: true)
//將定時器新增到執行迴圈
RunLoop.current.add(myTimer!, forMode: .commonModes)
let singleTap :UIGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(backAction))
self.view.isUserInteractionEnabled = true
self.view.addGestureRecognizer(singleTap)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
UIView.animate(withDuration: 0.6, animations: {()->Void in
self.closeImgView?.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI))
})
}
//新增選單按鈕
fileprivate func addMenu(){
let cols:Int = 3
var col:Int = 0
var row:Int = 0
var x:CGFloat = 0
var y:CGFloat = 0
let wh:CGFloat = 90
let margin:CGFloat = (UIScreen.main.bounds.size.width - CGFloat(cols) * wh )/(CGFloat(cols) + 1)
let oriY:CGFloat = 300
for i in 0 ..< ary.count{
let btn : MXMenuButton = MXMenuButton(type: .custom)
let img :UIImage = UIImage.init(named: "\(ary[i])")!
btn.setImage(img, for: .normal)
btn.setTitle(titleAry[i], for: .normal)
col = i % cols //當前列
row = i / cols //當前行
x = margin + CGFloat(col)*(margin+wh)
y = CGFloat(row) * (margin + wh) + oriY
btn.frame = CGRect(x:x,y:y,width:wh,height:wh)
//每次都是以最初位置的中心點為起始參照
btn.transform = CGAffineTransform(translationX: 0, y: self.view.bounds.size.height);
btn.tag = 1000 + i
btn.addTarget(self, action: #selector(btnClicked(btn:)), for: .touchUpInside)
itemButtons.append(btn)
self.view.addSubview(btn)
}
}
//新增closeImg
fileprivate func addCloseImg(){
let imgView : UIImageView = UIImageView(image: UIImage(named:"closeImg"))
imgView.frame = CGRect(x:self.view.center.x-15 ,y:self.view.frame.height-30 ,width:30 ,height:30)
self.view .addSubview(imgView)
self.closeImgView = imgView
}
//選單按鈕點選事件
func btnClicked(btn:MXMenuButton){
switch btn.tag {
case 1000:
if let str = btn.titleLabel?.text{
print(str)
}
case 1001:
print(""+(btn.titleLabel?.text)!)
case 1002:
print(""+(btn.titleLabel?.text)!)
case 1003:
print(""+(btn.titleLabel?.text)!)
case 1004:
print(""+(btn.titleLabel?.text)!)
case 1005:
print(""+(btn.titleLabel?.text)!)
default:
print(""+(btn.titleLabel?.text)!)
}
UIView.animate(withDuration: 0.5, animations: {()->Void in
btn.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
}, completion: {(finished:Bool)->Void in
//使用首尾式動畫區分閉包
UIView.beginAnimations("", context: nil)
UIView.setAnimationDuration(0.3)
btn.transform = .identity
UIView.commitAnimations();
})
}
//彈出選單
func popupBtn(){
if self.upIndex == self.itemButtons.count{
self.downIndex = self.itemButtons.count - 1
self.myTimer?.invalidate()
self.upIndex = 0
return;
}
let tempBtn:MXMenuButton = self.itemButtons[self.upIndex]
self.setUpOneBtnAnim(btn:tempBtn)
self.upIndex+=1
}
//設定按鈕從第一個開始向上滑動顯示
func setUpOneBtnAnim(btn:MXMenuButton){
UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0, options: .curveEaseIn, animations: {()->Void in
btn.transform = .identity;
}, completion: nil)
}
//返回
func backAction(){
self.myTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(popdownBtn), userInfo: nil, repeats: true)
//設定關閉動畫
UIView.animate(withDuration: 0.3, animations: {()->Void in
print(CGFloat(-M_PI_2*1.5))
self.closeImgView?.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_4))
})
}
//設定按鈕從最後一個開始向下滑動顯示
func popdownBtn(){
if self.downIndex == -1{
//pop當前頁面
_ = self.navigationController?.popViewController(animated: true)
self.myTimer?.invalidate()
return
}
let tempBtn:MXMenuButton = self.itemButtons[self.downIndex]
self.setDownOneBtnAnim(btn:tempBtn)
self.downIndex -= 1
}
//設定動畫
func setDownOneBtnAnim(btn:MXMenuButton){
UIView.animate(withDuration: 0.6, animations: {()->Void in
btn.transform = CGAffineTransform(translationX: 0, y: self.view.bounds.size.height)
}, completion: nil)
}
//解構函式
deinit {
print("執行解構函式")
}
}
MXMenuButton.swift
//
// MXMenuButton.swift
// SwiftDemo
//
// Created by turbomx on 2016/11/28.
// Copyright © 2016年 xiazy. All rights reserved.
//
import UIKit
open class MXMenuButton:UIButton{
override init(frame:CGRect){
super.init(frame: frame)
self.imageView?.contentMode = .center
self.titleLabel?.textAlignment = .center
self.setTitleColor(UIColor.black, for: .normal)
self.titleLabel?.font = UIFont.systemFont(ofSize: 12)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override open func layoutSubviews() {
super.layoutSubviews()
let imageX:CGFloat = 0
let imageY:CGFloat = 0
let imageW:CGFloat = self.bounds.size.width
let imageH:CGFloat = self.bounds.size.height * 0.8
self.imageView?.frame = CGRect(x:imageX,y:imageY,width:imageW,height:imageH)
let labelY:CGFloat = imageH
let labelH:CGFloat = self.bounds.size.height - labelY
self.titleLabel?.frame = CGRect(x:imageX,y:labelY,width:imageW,height:labelH)
}
}
原始碼:點我下載