视图通过边界
作为实现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))
链接地址: http://www.djcxy.com/p/96787.html
上一篇: views pass through boundaries
下一篇: How to avoid dynamics deformation using UIDynamicAnimator