为啥我无法检测到我使用 UIKit Dynamics 推离屏幕的 UIView 何时不再可见?
Posted
技术标签:
【中文标题】为啥我无法检测到我使用 UIKit Dynamics 推离屏幕的 UIView 何时不再可见?【英文标题】:Why am I unable to detect when my UIView I push off screen using UIKit Dynamics is no longer visible?为什么我无法检测到我使用 UIKit Dynamics 推离屏幕的 UIView 何时不再可见? 【发布时间】:2014-06-01 08:30:21 【问题描述】:我正在使用 UIKit Dynamics 将 UIView 推离屏幕,类似于 Tweetbot 在其图像叠加中执行它的方式。
我使用UIPanGestureRecognizer
,当他们结束手势时,如果他们超过速度阈值,它就会离开屏幕。
[self.animator removeBehavior:self.panAttachmentBehavior];
CGPoint velocity = [panGestureRecognizer velocityInView:self.view];
if (fabs(velocity.y) > 100)
self.pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.scrollView] mode:UIPushBehaviorModeInstantaneous];
[self.pushBehavior setTargetOffsetFromCenter:centerOffset forItem:self.scrollView];
self.pushBehavior.active = YES;
self.pushBehavior.action = ^
CGPoint lowestPoint = CGPointMake(CGRectGetMinX(self.imageView.bounds), CGRectGetMaxY(self.imageView.bounds));
CGPoint convertedPoint = [self.imageView convertPoint:lowestPoint toView:self.view];
if (!CGRectIntersectsRect(self.view.bounds, self.imageView.frame))
NSLog(@"outside");
;
CGFloat area = CGRectGetWidth(self.scrollView.bounds) * CGRectGetHeight(self.scrollView.bounds);
CGFloat UIKitNewtonScaling = 5000000.0;
CGFloat scaling = area / UIKitNewtonScaling;
CGVector pushDirection = CGVectorMake(velocity.x * scaling, velocity.y * scaling);
self.pushBehavior.pushDirection = pushDirection;
[self.animator addBehavior:self.pushBehavior];
我在检测我的视图何时完全从屏幕上消失时遇到了很多麻烦。
我的观点设置得相当简单。这是一个UIScrollView
,里面有一个UIImageView
。两者都在UIViewController
之内。我用平移手势移动了UIScrollView
,但想检测图像视图何时离开屏幕。
在action
块中,我可以在视图移动时对其进行监控,我尝试了两种方法:
1. 每次调用action
块时,为图像视图找到y
中的最低点。将其转换为视图控制器的参考点,我只是想看看当我向上“抛出”视图时,转换点的y
值何时小于 0(负)。 (这意味着视图中的最低点已经越过了视图控制器参考点的负y
值,位于视图控制器的可见区域上方。)
这没问题,除了我给lowestPoint
的x
值真的把一切都搞砸了。如果我选择最小的 X,即最左边的 X,它只会告诉我 UIView
的左下角何时离开屏幕。通常,由于视图可能会根据用户从哪里推动而旋转,右下角可能会在左下角之后离开屏幕,使其过早检测到它。如果我选择中间 X,它只会告诉我中间底部何时消失,等等。我似乎无法弄清楚如何告诉它“给我绝对最低的 y 值。
2.我试过CGRectIntersectsRect
,如上面的代码所示,它从来没有说它在外面,即使在它在任何可见区域之外拍摄几秒钟后也是如此。
我做错了什么?我应该如何检测到它不再可见?
【问题讨论】:
【参考方案1】:如果您查看UIDynamicItem
协议属性,您可以看到它们是center
、bounds
和transform
。所以UIDynamicAnimator
实际上只修改了这三个属性。我不太确定在动态动画期间frame
会发生什么,但根据我的经验,我可以看出它在动作块中的值并不总是可靠的。可能是因为框架实际上是由 CALayer 基于center
、transform
和bounds
计算的,如excellent blog post 中所述。
但您肯定可以在操作块中使用center
和bounds
。以下代码在与您类似的情况下对我有用:
CGPoint parentCenter = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
self.pushBehavior.action = ^
CGFloat dx = self.imageView.center.x - parentCenter.x;
CGFloat dy = self.imageView.center.y - parentCenter.y;
CGFloat distance = sqrtf(dx * dx + dy * dy);
if(distance > MIN(parentCenter.y + CGRectGetHeight(self.imageView.bounds), parentCenter.x + CGRectGetWidth(self.imageView.bounds)))
NSLog(@"Off screen!");
;
【讨论】:
以上是关于为啥我无法检测到我使用 UIKit Dynamics 推离屏幕的 UIView 何时不再可见?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 fs.readFileSync 不会检测到我的 json 文件
为啥服务器没有检测到我的 python 项目中的更改源代码?
Swift:将 SwiftUI 元素添加到 UIKit 项目:无法正确应用约束
XCUITest 无法检测到我动态生成的 tableView 的可访问性 id