仅从 1 个子视图平移 UIView

Posted

技术标签:

【中文标题】仅从 1 个子视图平移 UIView【英文标题】:Panning a UIView only from 1 subview 【发布时间】:2018-02-05 04:04:59 【问题描述】:

我有一个用作自定义警报的 UIView (alertView)。在这个 UIView 里面,我有几个交互。我希望这个自定义警报 (alertHeaderView) 的顶部能够被平移以移动 alertView,同时仍然保持 alertView 内容的功能。

我目前有这个一半的工作。在情节提要中,我将平移手势识别器添加到了整个 alertView。我的平移功能完美无缺,但它阻止了视图内发生的所有交互。这就是问题所在。

@IBAction func panAlert(_ sender: UIPanGestureRecognizer) 
    // ... All my pan code.

我已经为标题创建了一个出口:

@IBOutlet weak var alertHeaderView: UIView!

有没有一种方法可以平移整个 alertView,仅通过来自 alertHeaderView 的触摸?

【问题讨论】:

仅对 alertHeaderview 应用平移手势 这使它只围绕标题平移。不是整个视图。 在这种情况下,您可以通过在 UIview 中获取触摸位置来维护检查,即 AlertView 如果该触摸视图在所需的边界句柄视图中,则使用平移手势,否则没有翻译,简而言之,将平移添加到整个警报视图时用户触摸alertView检查触摸位置,然后进行翻译 我发布了一个肯定会帮助您获得所需输出的答案,谢谢 【参考方案1】:

这是我尝试过的代码 - 它限制视图从特定位置集移动

import UIKit

class AlertWithPan: UIViewController

    @IBOutlet weak var alertView: UIView!

    override func viewDidLoad()
    
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.alertView.isHidden = true
        self.addPanGesture()
    

    func addPanGesture()
    
        let gesture : UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action:#selector(AlertWithPan.handlePanGesture(panGesture:)))
        self.alertView.addGestureRecognizer(gesture)
    



    @objc func handlePanGesture(panGesture: UIPanGestureRecognizer)
    

        ///Get my Location
        let touchPosition = panGesture.location(in: self.alertView)
        print("currentTouch: \(touchPosition.y), ViewOrigin_Y: \(String(describing: panGesture.view?.frame.origin.y))")

        //Let us limit the frame Movement on specific location 
        //In your case you had initialised a header View supposingly it is having height 32 
        //So we will set TouchPosition not to move Ahead of that View
        //I am using here touch Location in AlertView 
        //Setting it to limit upto `self.alertView.frame.size.height*0.2`


        //self.alertView.frame.size.height*0.2 - This refers to Height of your Header View 
        //if a view having total height of Hundred then If I write self.alertView.frame.size.height*0.2
        //This means just 20 percent of height - 20 out of hundred 
        //we had added pan in AlertView , I.e So we need to set a proper height in which Pan will be allowed to set translation 
        //self.alertView.frame.size.height*0.2 - using this I made the view to move only in case if touch location is with in the header size I.e 20 
        // if you had provided static height of header 
        //Then Can get this by using like pan gesture.origin.y + header view height 
        // So check will be  touchPosition.y > Total of both
        if touchPosition.y > self.alertView.frame.size.height*0.2 
            print("High")
        
        else
            print("Low")
            ///Get the changes
            let translation = panGesture.translation(in: self.view)

            ///Move view to required Position
            panGesture.view!.center = CGPoint(x: panGesture.view!.center.x, y: panGesture.view!.center.y + translation.y)
            panGesture.setTranslation(CGPoint.zero, in: self.view)
        



    


    @IBAction func showMyAlertView(_ sender: Any)
    
        self.alertView.isHidden = false
    

我的故事板:

工作视频:

https://drive.google.com/open?id=1ZZuqxc34BUEZQ7WGFJiA2lU6ydIwqEjn

【讨论】:

感谢您的帮助!我现在正在浏览您的代码,在这里需要一点帮助: if touchPosition.y > self.alertView.frame.size.height*0.2 .我不确定这条线在做什么。我只想能够在 alertHeaderView 中检测到 touchPosition 从头开始,我明白了 :) 我修改了那行,所以“标题区域”与 alertHeaderView 的高度匹配,而不是整个 alertView 的 0.2%。谢谢你的帮助!! 我用清晰的描述编辑了我的答案,无论如何,欢迎,乐于帮助 感谢您编辑的描述。这有帮助。然而,发现了一个小错误。如果用户在内容区域(标题下方的区域)内点击,然后将手指向上拖动到“标题位置”,则视图会向上跳,因为手指进入了标题区域。有什么办法可以预防吗? 没错,我们想多了。我也这样做了 将保留此作为我的参考

以上是关于仅从 1 个子视图平移 UIView的主要内容,如果未能解决你的问题,请参考以下文章

RotationGesture 后平移 UIView 导致视图折叠

与平移手势闪烁视图相关的问题

创建一个 UIView 用作子视图

如何在 UIView swift 中重新加载特定的子视图?

如何挂钩子视图的子视图?

是否可以在按钮上启动滚动视图平移手势