如何在应用 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 无反弹的碰撞