Search code examples
iosswift3subviewuipangesturerecognizerevernote

Create a subView using CGPath and than adding UIPanGestureRecognizer on that subview


I have seen several answers about adding a GestureRecognzier to subViews but my problem is that I don't have the subView's frame available beforehand. I am drawing a CGPath and at the Touches Ended method, I want to create a new subView with frame equal to CGPath bounding box. After that, I want to drag that subView with PanGestureRecognizer. I am trying to implement Evernote crop functionality where the user selects a certain area of view and move it to other position. Is this the right approach to that solution?


Solution

  • Not quite understand the relationship between UIGestureRecognizer and .frame. you can simply add UIGestureRecognizer to object, once its init work finished. Try to add gesture in TouchEnd method directly after drawing subview.

    import UIKit
    
    class GestureResearchVC: UIViewController{
    
        var subViewByCGPath: UIView?
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        func createSubView(){
            //creat subview
            subViewByCGPath = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
            subViewByCGPath?.backgroundColor = UIColor.yellow
            let circlePath = UIBezierPath(arcCenter: CGPoint(x: 50,y: 50), radius: CGFloat(20), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
    
            let shapeLayer = CAShapeLayer()
            shapeLayer.path = circlePath.cgPath
            shapeLayer.strokeColor = UIColor.red.cgColor
    
            subViewByCGPath?.layer.addSublayer(shapeLayer)
            self.view.addSubview(subViewByCGPath!)
    
            //add pan gesture to subViewByCGPath
            let gesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(rec:)))
            subViewByCGPath?.addGestureRecognizer(gesture)
    }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            if subViewByCGPath == nil {
                print("touch end once")
                createSubView()
            }else{
                print("touch end repeatedly")
            }
        }
    
        func panGestureAction(rec: UIPanGestureRecognizer){
            print("pannnnnnn~")
            let transPoint = rec.translation(in: self.view)
            let x = rec.view!.center.x + transPoint.x
            let y = rec.view!.center.y + transPoint.y
    
            rec.view!.center = CGPoint(x: x, y: y)
            rec.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    
            //distinguish state
            switch rec.state {
                case .began:
                    print("began")
                case .changed:
                    print("changed")
                case .ended:
                    print("ended")
                default:
                    print("???")
            }
        }
    }