やりたいこと
UIScreenEdgePanGestureRecognizerを使って画面の端をスワイプするとメニュービューが端から半分ほど飛び出てくる画面を作りたい
経緯
参考記事を元に実装を行いましたが、シミュレーターで起動してみたところうまく実行できませんでした。
(スワイプを行っても全く反応しない状態)
UIViewControllerにメニュー画面(UIView)を重ねて実現しようとしています。
ViewController
1import UIKit 2 3class ViewController: UIViewController ,SideMenuDelegate{ 4 5 var sideView : SideMenu! 6 7 //@IBOutlet var RightEdgePanGesture: UIScreenEdgePanGestureRecognizer! 8 9 @IBOutlet var RightEdgePanGesture: UIScreenEdgePanGestureRecognizer! 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 let imageArray = [UIImage(named:"0.png")!,UIImage(named:"1.png")!,UIImage(named:"2.png")!] 15 sideView = SideMenu(image:imageArray, parentViewController:self) 16 sideView.delegate = self 17 self.view.addSubview(sideView) 18 RightEdgePanGesture.edges = .right 19 } 20 21 func EdgePanGesture(_ sender: UIScreenEdgePanGestureRecognizer) { 22 sideView.EdgePanGesture(sender: sender) 23 } 24 25 override func didReceiveMemoryWarning() { 26 super.didReceiveMemoryWarning() 27 // Dispose of any resources that can be recreated. 28 } 29 30 /* デリゲートメソッド */ 31 func onClickButton(sender: UIButton) { 32 print(sender.tag) 33 } 34 35}
SlideMenu
1import UIKit 2 3@objc protocol SideMenuDelegate { 4 func onClickButton(sender:UIButton) 5} 6 7class SideMenu: UIView { 8 var size: CGRect? 9 var swipeGesture : UISwipeGestureRecognizer! 10 var rightConstraint: NSLayoutConstraint! 11 var parentVC: UIViewController! 12 var isSideMenuhidden: Bool = true 13 14 //デリゲートのインスタンスを宣言 15 weak var delegate: SideMenuDelegate? 16 17 //イニシャライザー 18 init(image: [UIImage],parentViewController: UIViewController) { 19 self.size = CGRect(x:UIScreen.main.bounds.width, 20 y:0, 21 width:UIScreen.main.bounds.width*2, 22 height:UIScreen.main.bounds.height 23 ) 24 super.init(frame: size!) 25 //サイドメニューの背景色 26 self.backgroundColor = UIColor.darkGray 27 //サイドメニューの背景色の透過度 28 self.alpha = 0.8 29 self.buttonSet(num: image.count,image: image) 30 31 self.parentVC = parentViewController 32 33 //親ビューをタップしたときにメニューを下げる 34 let clearView = 35 UIView(frame:CGRect(x:0,y:0, 36 width:UIScreen.main.bounds.width*2/3, 37 height:UIScreen.main.bounds.height 38 )) 39 clearView.alpha = 1.0 40 parentVC.view.addSubview(clearView) 41 let tapGesture = UITapGestureRecognizer( 42 target: self, 43 action: #selector(self.clearViewTapped) 44 ) 45 tapGesture.numberOfTapsRequired = 1 46 clearView.addGestureRecognizer(tapGesture) 47 } 48 49 50 @objc func clearViewTapped(){ 51 if isSideMenuhidden == false { 52 isSideMenuhidden = true 53 UIView.animate(withDuration: 0.8, 54 animations: { 55 self.frame.origin.x = UIScreen.main.bounds.width 56 }, 57 completion:nil) 58 } 59 } 60 61 required init?(coder aDecoder: NSCoder) { 62 fatalError("init(coder:) has not been implemented") 63 } 64 65 //親ビューで指定した画像の数だけボタンを生成、配置 66 func buttonSet(num:Int, image:[UIImage]){ 67 for i in 0..<num{ 68 let button = 69 UIButton(frame:CGRect(x:10, 70 y:50+110*i, 71 width:90, height:90)) 72 //ボタンの画像 73 button.setImage(image[i], for: .normal) 74 //ボタンの四隅に余白をつける 75 button.imageEdgeInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) 76 //ボタンの背景色 77 button.backgroundColor = UIColor.yellow 78 // サイズの半分の値 (丸いボタンにするため) 79 button.layer.cornerRadius = 45 80 //ボタンにタグをつける 81 button.tag = i 82 button.addTarget(self, 83 action: #selector(self.onClickButton(sender:)), 84 for: .touchUpInside) 85 self.addSubview(button) 86 } 87 } 88 89 //画面の端からのスワイプを検出 90 public func EdgePanGesture(sender: UIScreenEdgePanGestureRecognizer) { 91 self.translatesAutoresizingMaskIntoConstraints = false 92 93 //移動量を取得する。 94 let move:CGPoint = sender.translation(in: parentVC.view) 95 96 //画面の端からの移動量 97 self.frame.origin.x += move.x 98 //画面表示を更新する。 99 self.layoutIfNeeded() 100 101 //ドラッグ終了時の処理 102 if(sender.state == UIGestureRecognizer.State.ended) { 103 if(self.frame.origin.x < parentVC.view.frame.size.width/3) { 104 //ドラッグの距離が画面幅の三分の一を超えた場合はメニューを出す 105 UIView.animate(withDuration: 0.8, 106 animations: { 107 self.frame.origin.x = UIScreen.main.bounds.width*2/3 108 }, 109 completion:nil) 110 isSideMenuhidden = false 111 }else { 112 //ドラッグの距離が画面幅の半分以下の場合はそのままビューを右に戻す。 113 UIView.animate(withDuration: 0.8, 114 animations: { 115 self.frame.origin.x = UIScreen.main.bounds.width 116 }, 117 completion:nil) 118 } 119 } 120 //移動量をリセットする。 121 sender.setTranslation(CGPoint.zero, in: parentVC.view) 122 } 123 124 /* デリゲートメソッド 親ビューコントローラーに委譲 */ 125 @objc func onClickButton(sender:UIButton){ 126 self.delegate?.onClickButton(sender: sender) 127 } 128 129 //Only override draw() if you perform custom drawing. 130 //An empty implementation adversely affects performance during animation. 131 // override func draw(_ rect: CGRect) { 132 // } 133 134}
ViewControllerに配置したUIScreenEdgePanGestureRecognizer
StoryBoard (ViewController)
方法2
似たような方法で他に参考記事を元に、スワイプでなくボタンを押すと画面の端からメニュー画面を出すことはうまくいきました。こちらの方が画面をstoryboardで全て管理できるのでやりやすいのですが、最終的に作りたいものはスワイプでメニュー画面を出現するものです。
コードは文字量の関係で省略m(_ _)m
シミュレーターで起動させて、ContentViewControllerのメニューを開くのボタンを押すとMenuViewControllerが左端から出現。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/11 02:40
2019/09/12 04:11