簡體   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