1

CustomPresentationControllerはカスタムアニメーションでアニメーションを出し入れします。iOS - 提示されたView ControllerをそのViewの外に触れないようにします。

この特定のコントローラは、画面サイズの50%で表示されます。提示すると、シャドウグレービューがpresentingViewControllerに追加されます。私は、デフォルトdismiss(:)メソッドを呼び出すNavBarcancelボタンをタップすると

私はpresentedViewControllerを却下することができます。私が達成しようとしている何

は多分グレーゾーンの内側に、presentedViewController外でタップを検出することであるので、私は何とかActionSheetを退けるよう、presentedViewControllerを消すことができますが、私はそれを行うことができなかったしました。私がこれまでに試したことを説明しましょう。

シャドウグレービューにUITapGestureRecognizerを追加しようとしましたが、別のコントローラを提示しているので、シャドウビューがトップ階層ビューにないためアクセスできない可能性がありますレコグナイザをブロックします。タップするとジェスチャハンドルは起動しません。

私はすぐにスワイプダウンを実装していますが、これを簡単に行うことができますが、タップアウト機能も同様に機能するようにしたいと考えています。

どのように私はこれに近づけることができますか?

アプリのイメージは以下の通りです:

screenshot

答えて

1

私はちょうど私のアプリの一つでこれを実装する必要がありました。

ビュー全体をカバーするボタンを追加してこのボタンを機能させました。このボタンをタップするとVCがトリガーされます。

ボタンが追加されたら、カスタムビューを上に追加できます。

これまでのところ、うまく機能しているようです。あなたはカスタムビューの下で目に見えないボタンを置くことを確認し、ストーリーボードを使用している場合

以下の私のコード

//————————————————————————————— 
    // MARK: View Life Cycle 
    //————————————————————————————— 

override func viewDidLoad() { 
    super.viewDidLoad() 
    view.backgroundColor = UIColor.clear //VC view background transparent 
    setupUI() 
} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    //Animate blackView opacity to 1 to give some depth 
    UIView.animate(withDuration: 0.4, delay: 0.2, options: .curveEaseInOut, animations: { 
     self.blackView.alpha = 1 
    }) 
} 

    //———————————————— 
    // MARK: Setup UI 
    //———————————————— 

    let blackView: UIView = { 
     let view = UIView() 
     view.alpha = 0.0 
     view.backgroundColor = UIColor.black.withAlphaComponent(0.6) 
     return view 
    }() 
    //Invisible button which covers the entire view that can be tapped 
    lazy var dismissLayerBtn: UIButton = { 
     let btn = UIButton() 
     btn.addTarget(self, action: #selector(tapToDismiss), for: .touchUpInside) 
     return btn 
    }() 

    @objc func tapToDismiss() { 
     print("tapToDimiss") 
     self.dismiss(animated: true, completion: nil) 
    } 

    let milestonePickerView: MilestonePickerView = { 
     let view = MilestonePickerView(frame: .zero) 
     return view 
    }() 

    func setupUI() { 

     view.addSubview(blackView) 
     view.addSubview(dismissLayerBtn) 
     view.addSubview(milestonePickerView) //Important to add the customView after the button. 

     blackView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0) 

     dismissLayerBtn.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0) 

     milestonePickerView.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 20, paddingBottom: 40, paddingRight: 20, width: 0, height: 400) 

//I'm using a custom extension to setup constraints (anchors) 
    } 

(私は、プログラム的に何のストーリーボードを全力を尽くすません)。

こちらがお役に立てば幸いです。

1

あなたがUITapGestureRecognizerで正しい軌道に乗っていました。ちょうどあなたのようなshouldRecognizeSimultaneouslyWithを実装していることを確認します。これは、ジェスチャが正しく発動できるようにする必要があり

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 
    return true 
} 

+0

hmm ...私は決してその財産を使用したことがないので、それを理解できなかった可能性があります。D 私はそれを試してみます。あなたにフィードバックします。 –

+0

それはうまくいきませんでした。そのプロパティを何らかの形で設定すると、ジェスチャ認識機能は決して起動しません。 ビューはトップビュー階層にないので、ユーザーは利用できないと考えるかもしれません。 提示されたビューとは独立して、画面上の任意の場所でタッチを検出する方法があるはずです。タッチ位置が提示されたポップアップよりも上にあるかどうかを確認してから、いつ解消するかを知っていました –

0

は私の次のコードを試してみてください。

あなたは、あなたがポップアップとしてで作業しているコントローラを発表内側にこのメソッドを実装する必要があります。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    // Here write down you logic to dismiss controller  
} 

これはうまくいきます。 :D

+0

動作しませんでした。 ポップアップビューのタイプが 'UICollectionView'なので、' collectionView?.isUserInteractionEnabled = false'を設定して、内部のタッチを検出する必要がありましたが、タッチを検出したにもかかわらずタッチがシャドウ内にあった場合は検出しません。 シャドウ領域に触れると 'touches(:)'メソッドが起動しません –

関連する問題