[英]Detecting visibility percentage of a UIView in iOS views
我需要找出目标 UIView object 在屏幕上是否可见。 根据我的研究,似乎共识是检查 UIView object 的window
属性是否是keyWindow
。 但这只是部分解决了我的问题,因为一个视图可能被另一个视图 object 部分阻塞。 例如:
灰色正方形的一半被蓝色矩形遮挡,因此灰色正方形对用户的可见度为 50%。
我正在研究的解决方案基本上如下,但它并不完全正确:
UIWindow *topWindow = [[[UIApplication sharedApplication].windows sortedArrayUsingComparator:^NSComparisonResult (UIWindow *win1, UIWindow *win2) {
if (win1.windowLevel < win2.windowLevel) {
return NSOrderedAscending;
} else if (win1.windowLevel > win2.windowLevel) {
return NSOrderedDescending;
}
return NSOrderedSame;
}] firstObject];
然后遍历topWindow
的所有子视图,找到我的目标视图object之后的所有子视图:
将 targetView 的 frame 和它之后的所有 subview 转换为topWindow
的坐标,用于检测是否有交集。
NSMutableArray *stack = [[NSMutableArray alloc] initWithArray:topWindow.subviews];
UIView *targetView = nil;
NSInteger targetViewTag = 10;
NSMutableArray *postViews = [NSMutableArray array]; // views detected after targetView, used for detection overlap with targetView
while ([stack count] > 0) {
UIView *curr = [stack lastObject];
[stack removeObject:curr];
if (curr.isHidden || curr.window == nil) {
continue;
}
if (curr.tag == targetViewTag) {
targetView = curr;
} else if (targetView) {
[postViews addObject:curr];
}
for (UIView *sub in [curr subviews]) {
[stack addObject:sub];
}
}
// if targetView is found:
if (targetView) {
float visiblePercentage = 100;
for (UIView *pw in postViews) {
// convert frames to topWindow for detecting intersection
CGRect swFrame = [targetView convertRect:targetView.frame toView:topWindow];
CGRect pwFrame = [pw convertRect:pw.frame toView:topWindow];
if (CGRectIntersectsRect(swFrame, pwFrame)) {
CGRect intersection = CGRectIntersection(swFrame, pwFrame);
CGFloat intersectArea = intersection.size.width * intersection.size.height;
CGFloat swArea = swFrame.size.width * swFrame.size.height;
// update visiblePercentage
visiblePercentage = visiblePercentage - (100 * intersectArea / swArea);
}
}
}
我不确定将不同子视图中的视图帧转换为topWindow
坐标是否是个好主意,但是visiblePercentage
看起来不正确,因为它给了我负数。 任何人都有更好的方法来计算部分/完全被阻止的视图的可见百分比? 谢谢!
在我的算法上花了更多时间后,我终于意识到为什么它对我不起作用,因为使用stack
数据结构遍历视图层次结构的方式会使blocking views
比targetView
更快地从堆栈中弹出。 因此,在以下行中进行更改后,可见性百分比的计算对我有用:
while ([stack count] > 0) {
UIView *curr = [stack lastObject];
[stack removeObject:curr];
if (curr.isHidden || curr.window == nil) {
continue;
}
if (curr.tag == targetViewTag) {
targetView = curr;
} else if (targetView == nil) { // NOTE: correct this line from else if (targetView)
[postViews addObject:curr];
}
for (UIView *sub in [curr subviews]) {
[stack addObject:sub];
}
}
堆栈数据结构首先在我的targetView
顶部弹出这些视图,这是解决我的问题的技巧。 无论如何,感谢您的关注:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.