如何在应用 UIKit Dynamics 的重力时获取 UIView 的帧更新?

Posted

技术标签:

【中文标题】如何在应用 UIKit Dynamics 的重力时获取 UIView 的帧更新?【英文标题】:How to get UIView's frame update while applying UIKit Dynamics' gravity to it? 【发布时间】:2015-08-24 16:07:54 【问题描述】:

我现在正在体验 UIKit Dynamics,这就是我想做的事情:

    使用重力将多个 UIView 实例从屏幕顶部“拖放”到底部 => OK 当每个视图与底部的距离为 100 像素时触发事件。 => 不行 :(

这是我尝试过的:

    在每个视图的“框架”属性上添加观察者 => 我不知道为什么,但从未调用过 observeValueForKeyPath(请参见下面的代码)... 为每个视图添加一个透明的碰撞边界并监听 UICollisionBehaviorDelegate => 这有点工作,但它不是我想要的行为。因为当然视图被边界“停止”了,我希望它下降

这是我的测试代码:

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 !")
            
        
    

使用此代码,视图将正确下降,但当视图距离底部 100 像素时不会触发任何事件

如果有任何帮助,我将不胜感激

【问题讨论】:

你是怎么做到的? 【参考方案1】:

一种方法是添加一个 UICollisionBehavior,在底部上方 100 像素处创建一个视图位置,并定义一个在您的项目与此碰撞时将调用的操作。

我现在无法为您创建示例,但http://www.raywenderlich.com/50197/uikit-dynamics-tutorial 会很有帮助,请查找名为“不可见边界和碰撞”的部分。虽然它是 Objective-C,但这应该不是问题,因为这很容易。

【讨论】:

正如我在原件中所说,我尝试了碰撞。但是碰撞的问题是......它碰撞了^^。而且我不希望这种行为,如果您愿意,我希望视图能够“通过”碰撞。这就是我尝试 KVO 没有成功的原因。 你说得对,对不起,我有点着急。如果您通过从 UICollisionBehavior 中删除有问题的项目(视图冲突)在检测到碰撞后将其删除,它不会起作用吗? 我刚试过,但是在我可以消除碰撞行为之前,下降的视图会反弹一点:(【参考方案2】:

我也一直在尝试做这项工作,确实应该在 UIDynamicAnimator 更新帧后有一个委托回调。

我已经设法解决了这个问题:

class FrameReportingView: UIView 

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

我使用的是UIPushBehavior,并且每个帧都设置了中心。您可以在FrameReportingView 上实现一个委托,以在中心更改后创建回调。

【讨论】:

以上是关于如何在应用 UIKit Dynamics 的重力时获取 UIView 的帧更新?的主要内容,如果未能解决你的问题,请参考以下文章

UIKit Dynamics UICollisionBehavior 无反弹的碰撞

UIKit Dynamics 用碰撞改变视图框架

UIKit Dynamics 的性能问题

ListView 项目滚动动画(类似“UIKit Dynamics”)

带有平移、旋转和捏合手势的 UIKit Dynamics

UIKit Dynamics 和 UIKit Animation 有啥区别?