繁体   English   中英

UICollisionBehavior - 视图通过边界

[英]UICollisionBehavior - views pass through boundaries

作为实现UICollisionBehaviour的一部分,我为屏幕边缘设置了边界。 然后我添加了一些视图,最后将一个UIPanGestureRecognizer附加到其中一个。

现在我可以使用我的可拖动视图来推动较小的视图。

锤时间!

问题:如果我将较小的视角转向并将其推向屏幕边缘,它最终将滑过边界并被困在另一侧。 我用来击打和推动其他视图的“锤子视图”也会陷入界限。 即它在屏幕的一侧被卡住/不可拖动。

我做了一个非常小的例子,看看当我的视图很少而且没有相互冲突的行为时我是否可以重现它,视图仍然可以通过边界。 无论是UIDynamics都无法处理,或者(更有可能)我以某种方式配置错误。

下面的小例子有奇怪的行为:

class ViewController: UIViewController {

var animator: UIDynamicAnimator?
var collisionBehaviour: UICollisionBehavior?
var panBehaviour: UIAttachmentBehavior?

override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    setup()
}

func setup() {
    //setup collisionBehaviour and animator
    collisionBehaviour = UICollisionBehavior()
    collisionBehaviour!.collisionMode = UICollisionBehaviorMode.allZeros
    animator = UIDynamicAnimator(referenceView: view)

    //add boundaries
    collisionBehaviour!.addBoundaryWithIdentifier("verticalMin", fromPoint: CGPointMake(0, 0), toPoint: CGPointMake(0, CGRectGetHeight(view.frame)))
    collisionBehaviour!.addBoundaryWithIdentifier("verticalMax", fromPoint: CGPointMake(CGRectGetMaxX(view.frame), 0), toPoint: CGPointMake(CGRectGetMaxX(view.frame), CGRectGetHeight(view.frame)))
    collisionBehaviour!.addBoundaryWithIdentifier("horizontalMin", fromPoint: CGPointMake(0, CGRectGetMaxY(view.frame)), toPoint: CGPointMake(CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame)))
    collisionBehaviour!.addBoundaryWithIdentifier("horizontalMax", fromPoint: CGPointMake(0, 0), toPoint: CGPointMake(CGRectGetMaxX(view.frame), 0))

    //        collisionBehaviour!.translatesReferenceBoundsIntoBoundary = true // same effect as the above boundaries
    //setup up some round views to push around
    for i in 0..<5 {
        let ball = UIView(frame: CGRectMake(0, 30, 50, 50))
        ball.center = view.center
        ball.backgroundColor = UIColor.greenColor()
        ball.layer.cornerRadius = CGRectGetWidth(ball.frame) * 0.5
        view.addSubview(ball)
        collisionBehaviour!.addItem(ball)
    }

    //setup a hammer view which can be dragged and used to squeze the ball views of the screen
    let hammer = UIView(frame: CGRectMake(0, 0, 100, 100))
    hammer.backgroundColor = UIColor.redColor()
    view.addSubview(hammer)
    collisionBehaviour!.addItem(hammer)

    let noRotationBehaviour = UIDynamicItemBehavior(items: [hammer])
    noRotationBehaviour.allowsRotation = false
    animator!.addBehavior(noRotationBehaviour)

    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: Selector("handlePan:"))
    hammer.addGestureRecognizer(panGestureRecognizer)

    //"start" the collision detection
    animator!.addBehavior(collisionBehaviour!)
}

//Move the hammer around
func handlePan(recognizer: UIPanGestureRecognizer) {
    if let view = recognizer.view {
        let location = recognizer.locationInView(self.view)
        switch recognizer.state {
        case .Began:
            panBehaviour = UIAttachmentBehavior(item: view, attachedToAnchor: location)
            animator!.addBehavior(panBehaviour!)
            println("begin")
        case .Changed:
            panBehaviour!.anchorPoint = location
            println("change \(location)")
        case .Ended:
            println("ended")
            animator!.removeBehavior(panBehaviour!)
        default:
            println("done")
        }
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

谢谢你给予的任何帮助。

好消息:你没有做错任何事。 坏消息:这是预期的行为。 你的锤子正在将视图推向参考边界,直到它最终突破,因为模型的物理特性表明它应该做什么。 参考边界不是不能越过的边界,它只定义物理规则一致应用的区域。

这没有真正记录,但UICollisionBehavior的页面指出:

设置动态项的初始位置时,必须确保其边界不与任何碰撞边界相交。 这种放错位置的项目的动画行为是未定义的。

这只是部分正确,在你的情况下(和我一样)如果一个项目在初始化之后超出边界,它的行为也是未定义的。

我试图在视图的右侧安排一组球。 最右边的球下面有一个锚点。 黄色视图是参考视图,一切都很好...... 这很有效

但是,当我向他们添加更多的球时他们指出他们已经不再合适了,他们就会开始蹦出来。 事实上,图像右上角的那个从底部中心弹出,并逆时针绕参考视图滚动到靠近锚点。 这已破了

更新:对于解决方案,您可以设置collisionBehaviors的collisionDelegate并捕获碰撞的开始和结束,然后将视图移回边界并远离锤子,使其看起来像是逃脱的。

正如您所知,translatesReferenceBoundsIntoBoundary相当于addBoundaryWithIdentifier调用的集合。

使用:

collisionBehaviour!.translatesReferenceBoundsIntoBoundary = true 

与...一样:

//add boundaries
    collisionBehaviour!.addBoundaryWithIdentifier("verticalMin", fromPoint: CGPointMake(0, 0), toPoint: CGPointMake(0, CGRectGetHeight(view.frame)))
    collisionBehaviour!.addBoundaryWithIdentifier("verticalMax", fromPoint: CGPointMake(CGRectGetMaxX(view.frame), 0), toPoint: CGPointMake(CGRectGetMaxX(view.frame), CGRectGetHeight(view.frame)))
    collisionBehaviour!.addBoundaryWithIdentifier("horizontalMin", fromPoint: CGPointMake(0, CGRectGetMaxY(view.frame)), toPoint: CGPointMake(CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame)))
    collisionBehaviour!.addBoundaryWithIdentifier("horizontalMax", fromPoint: CGPointMake(0, 0), toPoint: CGPointMake(CGRectGetMaxX(view.frame), 0))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM