swiftcollisionuibezierpathuikit-dynamics

swift UIBezierPath collision boundary issues ( UIKit Dynamics )


Hi I have an app where the user can draw a bezier path with finger and it assigns this as a collision boundary for falling objects. It works!... But! It appears the Bézier curves are closing the path (hidden) and this also becomes a boundary.

So if I draw a convex curve it works perfect. But if I draw a concave curve the object will not enter the curve. Any help appreciated. I need to open the curves somehow! code below

override func draw(_ rect: CGRect) {
         super.draw(rect)
         
       guard let context = UIGraphicsGetCurrentContext() else {
             return
         }
         
         animator = UIDynamicAnimator(referenceView: self)
         gravity = UIGravityBehavior()
         animator.addBehavior(gravity)
         gravity.gravityDirection = CGVector(dx: 0, dy: 0.1)
         collision = UICollisionBehavior(items: [hamburger])
         collision.collisionDelegate = self
         collision.addBoundary(withIdentifier: "belt" as NSCopying, for: UIBezierPath(rect: belt.frame))
         
         animator.addBehavior(collision)

     
         
         collision.addItem(hamburger)
         gravity.addItem(hamburger)
         
         collision.translatesReferenceBoundsIntoBoundary = true
         
         let itemBehaviour = UIDynamicItemBehavior(items: [hamburger])
         itemBehaviour.elasticity = 0.1
         animator.addBehavior(itemBehaviour)
         
         
         lines.forEach { (line) in
             for (i, p) in (line.points?.enumerated())! {
                 if i == 0 {
                     context.move(to: p)
                 } else {
                     context.addLine(to: p)
                 }
                 context.setStrokeColor(line.color?.withAlphaComponent(line.opacity ?? 1.0).cgColor ?? UIColor.systemBlue.cgColor)
                 context.setLineWidth(line.width ?? 10.0)
                 lineboundary = UIBezierPath(cgPath: context.path!)
                 collision.addBoundary(withIdentifier: "linedrawn" as NSCopying, for: lineboundary)
             }
             context.setLineCap(.round)
             context.strokePath()
        
         }
         
         
         
     }

Solution

  • UIKit Dynamics does not permit concave paths. But you can add them as separate UICollisionBehavior instances:

    for index in points.indices.dropFirst() {
        let path = UIBezierPath()
        path.move(to: points[index-1])
        path.addLine(to: points[index])
    
        let collision = UICollisionBehavior(items: [droppedView])
        collision.addBoundary(withIdentifier: "\(index)" as NSString, for: path)
        animator.addBehavior(collision)
    }
    

    That results in:

    enter image description here