🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1968閲覧

スワイプすると出てくるメニューがうまく実行できない

samson66

総合スコア35

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/09/11 01:55

編集2019/09/11 02:31

やりたいこと
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

storyboard
イメージ説明

シミュレーターで起動させて、ContentViewControllerのメニューを開くのボタンを押すとMenuViewControllerが左端から出現。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

自分も検証してみました。

RightEdgePanGesture.edges = .right

はstoryboard上で指定できました。

イメージ説明

おそらく、ジェスチャとfunc EdgePanGesture(_ sender: UIScreenEdgePanGestureRecognizer)がつながっていませんので、
こんな感じでイベントハンドラを作ってください。

イメージ説明

シミュレーターでも問題なく動作することを確認済みです。

投稿2019/09/11 02:13

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

samson66

2019/09/11 02:40

ありがとうございます! 指定の方法でやってみたところ無事に反応しました。 追加の質問ですみませんが、現状の実装から 追記で載せた方法2のようにコードからではなくstoryboardで作ったメニュー画面を組み込ませる場合はどのように行えば良いのでしょうか? UIViewクラスのviewcontrollerをstoryboardに配置して実装していく形になりますでしょうか?
samson66

2019/09/12 04:11

追記: 方法2のやりかたでstoryboardにメニューviewcontrollerをセットし、関数をいくつか用意して それを @IBAction func EdgePanGesture(_ sender: Any) { } の中にセットしたらstoryboardで作った viewcontrollerを表示することに成功しましたm(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問