iosswifteventstouch

Touch event on Visible Portion of Views ios swift 4


I am working of Photo Collage which is in Swift4 , I had created collage using UIBezierPath as Below

enter image description here

I have 5 scroll views in Storyboard and the sequence of Scrollviews as Below

enter image description here

Using Following code I am creating Shapes :

    var path1 = UIBezierPath()
    path1.move(to: CGPoint(x: 0, y: 0))
    path1.addLine(to: CGPoint(x: superView.frame.width / 2, y: 0))
    path1.addLine(to: CGPoint(x: 0, y: superView.frame.width / 2))
    path1.addLine(to: CGPoint(x: 0, y: 0))

    var borderPathRef1 = path1.cgPath

    var borderShapeLayer1 = CAShapeLayer()
    borderShapeLayer1.path = borderPathRef1

    scroll1.layer.mask = borderShapeLayer1
    scroll1.layer.masksToBounds = true


    var path2 = UIBezierPath()
    path2.move(to: CGPoint(x: 0, y: 0))
    path2.addLine(to: CGPoint(x: superView.frame.width / 2, y: 0))
    path2.addLine(to: CGPoint(x: superView.frame.width / 2, y: superView.frame.width / 2))
    path2.addLine(to: CGPoint(x: 0, y: 0))

    var borderPathRef2 = path2.cgPath

    var borderShapeLayer2 = CAShapeLayer()
    borderShapeLayer2.path = borderPathRef2

    scroll2.layer.mask = borderShapeLayer2
    scroll2.layer.masksToBounds = true

Now the issue is I am not able to get touch event of Scrollviews as Scroll5 is on top. I want to get Touch on Overlapped views like Scroll1, Scroll2 and so on. In Short I need touch event for particular view on the portion of area where the view is visible.

See The Image Below Where I want Touch for Views.

enter image description here

How can I get touch on Overlapped Views?

Please Help!


Solution

  • You have to be sure that you set the superView of scrollview to isUserInterfaceEnabled=true first.

    To get overlapped views touch event:

    here is my code:

    class CustomView: UIView {
    let view1: UIView
    let view2: UIView
    let view3: UIView
    let view4: UIView
    let view5: UIView
    
    override init(frame: CGRect) {
        view1 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        view1.backgroundColor = UIColor.black
        view1.isUserInteractionEnabled = true
        view2 = UIView(frame: CGRect(x: 100, y: 0, width: 100, height: 100))
        view2.backgroundColor = UIColor.orange
        view2.isUserInteractionEnabled = true
        view3 = UIView(frame: CGRect(x: 0, y: 100, width: 100, height: 100))
        view3.backgroundColor = UIColor.blue
        view3.isUserInteractionEnabled = true
        view4 = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
        view4.backgroundColor = UIColor.brown
        view4.isUserInteractionEnabled = true
        view5 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
        view5.tag = 121
        view5.backgroundColor = UIColor.red
        super.init(frame: frame)
        self.addSubview(view1)
        self.addSubview(view2)
        self.addSubview(view3)
        self.addSubview(view4)
        self.addSubview(view5)
        view1.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(touchAction)))
    }
    
    @objc func touchAction () {
        print("----------- touch view 1")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if (view1.point(inside: self.convert(point, to: view1), with: event)) {
            return view1
        }
        return self
    }
    

    }

    The function hitTest decides that which view you are touching, so you just need to return the overlapped view.