检测呈现视图之外的触摸以将其关闭

Posted

技术标签:

【中文标题】检测呈现视图之外的触摸以将其关闭【英文标题】:Detect a touch outside of presented view to dismiss it 【发布时间】:2020-07-29 23:47:52 【问题描述】:

所以我有一个在单击按钮时显示的侧边菜单,我想知道你们是否可以帮助我找到如何检测是否在该侧边菜单视图之外发生了点击,以便我可以将其关闭。 我已经环顾四周,我看到的只是已弃用的东西和错误,我不能使用任何东西。 这是我的动画代码:

    import UIKit

 class SlideInTransition: NSObject, UIViewControllerAnimatedTransitioning 

var isPresenting = false

func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval 
    return 0.3


func animateTransition(using transitionContext: UIViewControllerContextTransitioning) 
    guard let toViewController = transitionContext.viewController(forKey: .to),
    let fromViewController = transitionContext.viewController(forKey: .from) else return 
    
    let containerView = transitionContext.containerView
    
    let finalWidth = toViewController.view.bounds.width * 0.8
    let finalHeight = toViewController.view.bounds.height
    
    if isPresenting
        
        containerView.addSubview(toViewController.view)
        
        toViewController.view.frame = CGRect(x: -finalWidth, y: 0, width: finalWidth, height: finalHeight)
    
    
    let transform = 
        toViewController.view.transform = CGAffineTransform(translationX: finalWidth, y: 0)
    
    
    let identity = 
        fromViewController.view.transform = .identity
    
    
    
    let duration = transitionDuration(using: transitionContext)
    let isCancelled = transitionContext.transitionWasCancelled
    UIView.animate(withDuration: duration, animations: 
        self.isPresenting ? transform() : identity()
    )(_) in
        transitionContext.completeTransition(!isCancelled)
     


【问题讨论】:

【参考方案1】:

我的应用程序中实际上有这样的东西。您可以做的是添加一个覆盖整个视图的 UIView() 。确保此视图位于除菜单之外的所有内容之前!将 UIView() userInteraction 设置为 false。显示菜单时,只需将视图设置为难以处理。然后放置一个触摸识别器,这样当它被触摸时菜单就会消失!

我也喜欢将视图背景设置为黑色,alpha 为 0.25!然后当菜单隐藏时,alpha 为零,当它显示时,将其设置为 0.25。当菜单显示时,它会使背景变暗,因此它既实用又美观。

    class BackGroundView: UIView 
    
        override init(frame: CGRect) 
            super.init(frame: frame)
            SetUpView()
        
        
        required init?(coder: NSCoder) 
            fatalError("init(coder:) has not been implemented")
        
        
        func SetUpView()
            backgroundColor = .black
            alpha = 0
            isUserInteractionEnabled = false
        
        
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

    // Here's where you would hide the menu


           
        
            
  func MenuIsShown(menuWillShow: Bool)
    
        if(menuWillShow)
            isUserInteractionEnabled = true
             UIView.animate(withDuration: 0.2) 
            alpha = 0.45
            
         else
            isUserInteractionEnabled = false

             UIView.animate(withDuration: 0.2) 
            alpha = 0
            
        
    
    
            
            func AddViewToScene(view: UIView)
             


            view.addSubview(self)
            translatesAutoresizingMaskIntoConstraints = false
            topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
            leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
            trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    
            
        
        
        
    

然后你可以称它为:

    class ViewController: UIViewController
    

    override func viewDidLoad() 
        super.viewDidLoad()
        

     let dimView = BackGroundView()
     dimView.AddViewToScene(view: view)

    
    
   


【讨论】:

以上是关于检测呈现视图之外的触摸以将其关闭的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 UIViewController 外部的点击/触摸

iOS - 关闭呈现的视图控制器触摸其视图外部

需要在 iOS 的覆盖视图中阻止除特定触摸之外的所有触摸

当在 tableview 之外触摸时。如何关闭 tableView? [复制]

子视图中的触摸检测

裁剪边界之外的 UIScrollview 子视图未接收到触摸