1

我有一個CustomPresentationController它使用自定義動畫進行動畫和動畫;iOS - 關閉顯示視圖控制器觸及其​​外部視圖

這個特定的控制器會在屏幕尺寸的50%處顯示出來,而當我呈現它時,我會在presentingViewController上添加一個陰影灰色視圖,以便增加一些深度。

我只能駁回presentedViewController如果我在NavBar我稱之爲默認dismiss(:)方法挖掘cancel按鈕。

我試圖做到的是檢測水龍頭presentedViewController外面,也許是灰色地帶裏面,這樣我就可以關閉該presentedViewController,不知何故像解僱一名ActionSheet,但我沒能做到這一點。讓我解釋我到目前爲止所嘗試的。

我試圖將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

嗯......我從來沒有使用過這個屬性,這可能是我爲什麼無法弄清楚的原因: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(:)'方法 –

相關問題