Joe
Joe

Reputation: 3931

Panning a UIView only from 1 subview

I have a UIView (alertView) that serves as a custom alert. Inside this UIView, I have several pieces of interaction. I would like just the top portion of this custom alert (alertHeaderView) to be able to be panned to move the alertView, while still maintaining the functionality of the alertView contents.

I currently have this half-working. In storyboard, I added the pan gesture recognizer to the whole alertView. My pan functionality works perfect, but it's preventing all the interaction from happening within the view. This is the problem.

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

I've created an outlet for the header:

@IBOutlet weak var alertHeaderView: UIView!

Is there a way I can pan the entire alertView, ONLY from touches from alertHeaderView?

Upvotes: 0

Views: 392

Answers (1)

iOS Geek
iOS Geek

Reputation: 4855

here is my tried code - it limit the view to be moved from specific location set

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
    }
}

my Storyboard:

enter image description here

Working Video :

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

Upvotes: 1

Related Questions