简体   繁体   English

如何在将UIKit Dynamics的重力应用于UIView时更新UIView的框架?

[英]How to get UIView's frame update while applying UIKit Dynamics' gravity to it?

I'm experiencing UIKit Dynamics right now and here is what I would like to do : 我现在正在体验UIKit Dynamics,这是我想做的事情:

  1. "Drop" multiple UIView instances from the top of the screen to the bottom using gravity => OK 使用重力=> 确定将多个UIView实例从屏幕顶部“拖放”到底部
  2. Trigger an event when each view's distance from the bottom is like 100px. 当每个视图与底部的距离为100px时触发事件。 => NOT OK :( => 不好:(

Here is what I tried : 这是我尝试的:

  1. Add on observer on the "frame" property for each view => I don't know why but observeValueForKeyPath is never called (see code below)... 在每个视图的“框架”属性上添加观察者=>我不知道为什么,但是从未调用过watchValueForKeyPath (请参见下面的代码)...
  2. Add a transparent collision boundary to each view and listen to UICollisionBehaviorDelegate => This kinda works but it is not the behavior I want. 向每个视图添加透明的碰撞边界,并收听UICollisionBehaviorDelegate =>这种方法确实可行,但这不是我想要的行为。 Because of course the view is "stopped" by the boundary and I want it to go down 因为当然,视图被边界“停止”了,我希望它向下

This is my test code : 这是我的测试代码:

var animator: UIDynamicAnimator!
var gravity: UIGravityBehavior!
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    self.animator = UIDynamicAnimator(referenceView: view)
    self.gravity = UIGravityBehavior()
    self.animator.addBehavior(gravity)

    let timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("createView"), userInfo: nil, repeats: true)
}

func createView() {
    var newView = UIView(frame: CGRectMake((UIScreen.mainScreen().bounds.size.width/2) - 20, -40, 40, 40))
    self.view.addSubview(newView)

    self.gravity.addItem(newView)

    newView.addObserver(self, forKeyPath: "frame", options: NSKeyValueObservingOptions.New, context: nil)
}

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    if keyPath == "frame" {
        if let newView = object as? UIView {
            println(newView.frame.origin.y)
            if (newView.frame.origin.y > UIScreen.mainScreen().bounds.size.height - 100) {
                println("Trigger event !")
            }
        }
    }
}

With this code, the views will get down correctly but no event will be triggered when it the views are 100px far from the bottom 使用此代码,视图将正确下降,但是如果视图离底部100px远,则不会触发任何事件

I would greatly appreciate any help 我将不胜感激任何帮助

A way to do it is by adding an UICollisionBehavior, creating a view position 100px above the bottom and define an action which would be called when your items collide with this. 一种方法是添加一个UICollisionBehavior,在底部上方创建一个100px的视图位置,并定义一个动作,当您的项目与此碰撞时将调用该动作。

I can't create a sample for you now, but http://www.raywenderlich.com/50197/uikit-dynamics-tutorial will be a great help, look for a section called "Invisible boundaries and collisions". 我现在无法为您创建示例,但是http://www.raywenderlich.com/50197/uikit-dynamics-tutorial将提供很大的帮助,请查找“隐形边界和碰撞”部分。 It's objective-C, though, but that shouldn't be a problem as this is pretty easy. 虽然是Objective-C,但这不应该成为问题,因为这很容易。

I've been trying to make this work too, really there should be a delegate callback from UIDynamicAnimator after it updates frames. 我也一直在尝试使其工作,实际上,在更新框架之后,应该从UIDynamicAnimator中进行委托回调。

I've managed to solve it like this: 我设法解决了这个问题:

class FrameReportingView: UIView {

    override var center: CGPoint {
        didSet{
            print("center: \(center)")
        }
    }
}

I'm using a UIPushBehavior and the center is set each frame. 我正在使用UIPushBehavior并且在每个帧中设置了中心。 You can implement a delegate on FrameReportingView to create a callback after the center is changed. 您可以在FrameReportingView上实现委托,以在更改中心后创建回调。

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

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