首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >UICollisionBehavior -视图通过边界

UICollisionBehavior -视图通过边界
EN

Stack Overflow用户
提问于 2015-01-15 21:24:52
回答 1查看 4.7K关注 0票数 18

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

现在,我可以用我的拖曳的视图来推开较小的视图。

问题:如果我将一个较小的视图转角,并继续将它推到屏幕边缘,它最终会滑过边界,被困在另一边。我用来打和推其他视图的“锤子视图”也会被困在边界里。也就是说,它被粘在/不能拖到屏幕的侧面。

我做了一个很小的例子,看看我是否能复制它,当我有很少的观点,没有冲突的行为,观点仍然是通过边界。要么UIDynamics不能很好地处理,要么(更可能)我配置错了。

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

代码语言:javascript
运行
复制
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.
}

}

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-22 02:36:15

好消息:你没做错什么。坏消息:这是预期的行为。你的锤子把视图推到参考边界上,直到它最终突破,因为你的模型的物理说,这是它应该做的。参考边界不是一个不能跨越的边界,它只定义了一个你的物理规则一致适用的区域。

这并不是真正的文档,但是UICollisionBehavior的页面声明:

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

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

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

但是,当我增加了更多的球,他们指出他们不能再适应,他们会开始弹出。事实上,在右上角的图像弹出的底部中心,并围绕参考视图逆时针滚动,以接近锚点。

UPDATE:作为解决方案,您可以设置collisionBehaviors的collisionDelegate,捕获碰撞的开始和结束,然后将视图移回边界,远离锤子,使其看起来就像逃脱了一样。

正如您已经知道的,translatesReferenceBoundsIntoBoundary等同于一组addBoundaryWithIdentifier调用。

使用:

代码语言:javascript
运行
复制
collisionBehaviour!.translatesReferenceBoundsIntoBoundary = true 

与:

代码语言:javascript
运行
复制
//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))
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27973250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档