如何获得部分从屏幕上平移的 UIView 的可见部分?
How do I get the visible portion of a UIView that is partially panned off the screen?
我有一个 UIView,我使用平移手势将其移动到屏幕的一侧,现在 UIView 仅部分显示在屏幕上。如何获得仅包含 UIView 可见部分的 CGRect,并且在原始视图的坐标中?
我已经尝试将 CGRectIntersect()
组合用于 UIView.frame
矩形和 [UIScreen mainscreen].bounds
矩形,如下所示:
CGRect rect = CGRectIntersection([UIScreen mainScreen].bounds,
view.frame);
我一直无法正确解析匹配坐标系。
您首先需要将置换视图的 CGRect 转换到主屏幕的坐标系。
你可以试试
if let mainVC = UIApplication.shared.keyWindow?.rootViewController {
let translatedRect = mainVC.view.convert(myTestView.frame, from: view)
let intersection = translatedRect.intersection(mainVC.view.frame)
}
这首先找到主 rootViewController,并将视图的框架平移到 rootViewController 的坐标系,然后找到交点。即使您的移位视图嵌套在多层视图中,这也能正常工作。
经过一些(几个小时的)实验,我想出了这个解决方案:
// return the part of the passed view that is visible
- (CGRect)getVisibleRect:(UIView *)view {
// get the root view controller (and it's view is vc.view)
UIViewController *vc = UIApplication.sharedApplication.keyWindow.rootViewController;
// get the view's frame in the root view's coordinate system
CGRect frame = [vc.view convertRect:view.frame fromView:view.superview];
// get the intersection of the root view bounds and the passed view frame
CGRect intersection = CGRectIntersection(vc.view.bounds, frame);
// adjust the intersection coordinates thru any nested views
UIView *loopView = view;
do {
intersection = [loopView convertRect:intersection fromView:loopView.superview];
loopView = loopView.superview;
} while (loopView != vc.view);
return intersection; // may be same as the original view frame
}
我首先尝试将根视图转换为目标视图的坐标,然后在视图框架上执行 CGRectIntersect,但没有成功。但是我让它以相反的方式为 UIViews 工作,根视图作为它们的超级视图。然后经过一些探索之后,我发现我必须通过视图层次结构来导航子视图。
它适用于父视图是根视图的 UIView,也适用于作为其他视图的子视图的 UIView。
我通过在初始视图上的这些可见矩形周围绘制边框来测试它,并且效果很好。
但是...如果 UIView 被缩放 (!=1) 并且是另一个 UIView 的子视图而不是根视图,它就不能正常工作。结果可见矩形的原点偏移了一点。如果视图在子视图中,我尝试了几种不同的方法来调整原点,但我想不出一个干净的方法来做到这一点。
我已将此方法添加到我的实用程序 UIView 类别,以及我一直在开发或获取的所有其他 "missing" UIView 方法。 (Erica Sadun 的变身术……我不配……)
这确实解决了我正在处理的问题。所以我会 post 另一个关于缩放问题的问题。
编辑:
在处理缩放问题的问答时,我也为这个问题想出了一个更好的答案:
// return the part of the passed view that is visible
- (CGRect)getVisibleRect:(UIView *)view {
// get the root view controller (and it's view is vc.view)
UIViewController *vc = UIApplication.sharedApplication.keyWindow.rootViewController;
// get the view's frame in the root view's coordinate system
CGRect rootRect = [vc.view convertRect:view.frame fromView:view.superview];
// get the intersection of the root view bounds and the passed view frame
CGRect rootVisible = CGRectIntersection(vc.view.bounds, rootRect);
// convert the rect back to the initial view's coordinate system
CGRect visible = [view convertRect:rootVisible fromView:vc.view];
return visible; // may be same as the original view frame
}
我有一个 UIView,我使用平移手势将其移动到屏幕的一侧,现在 UIView 仅部分显示在屏幕上。如何获得仅包含 UIView 可见部分的 CGRect,并且在原始视图的坐标中?
我已经尝试将 CGRectIntersect()
组合用于 UIView.frame
矩形和 [UIScreen mainscreen].bounds
矩形,如下所示:
CGRect rect = CGRectIntersection([UIScreen mainScreen].bounds,
view.frame);
我一直无法正确解析匹配坐标系。
您首先需要将置换视图的 CGRect 转换到主屏幕的坐标系。
你可以试试
if let mainVC = UIApplication.shared.keyWindow?.rootViewController {
let translatedRect = mainVC.view.convert(myTestView.frame, from: view)
let intersection = translatedRect.intersection(mainVC.view.frame)
}
这首先找到主 rootViewController,并将视图的框架平移到 rootViewController 的坐标系,然后找到交点。即使您的移位视图嵌套在多层视图中,这也能正常工作。
经过一些(几个小时的)实验,我想出了这个解决方案:
// return the part of the passed view that is visible
- (CGRect)getVisibleRect:(UIView *)view {
// get the root view controller (and it's view is vc.view)
UIViewController *vc = UIApplication.sharedApplication.keyWindow.rootViewController;
// get the view's frame in the root view's coordinate system
CGRect frame = [vc.view convertRect:view.frame fromView:view.superview];
// get the intersection of the root view bounds and the passed view frame
CGRect intersection = CGRectIntersection(vc.view.bounds, frame);
// adjust the intersection coordinates thru any nested views
UIView *loopView = view;
do {
intersection = [loopView convertRect:intersection fromView:loopView.superview];
loopView = loopView.superview;
} while (loopView != vc.view);
return intersection; // may be same as the original view frame
}
我首先尝试将根视图转换为目标视图的坐标,然后在视图框架上执行 CGRectIntersect,但没有成功。但是我让它以相反的方式为 UIViews 工作,根视图作为它们的超级视图。然后经过一些探索之后,我发现我必须通过视图层次结构来导航子视图。
它适用于父视图是根视图的 UIView,也适用于作为其他视图的子视图的 UIView。
我通过在初始视图上的这些可见矩形周围绘制边框来测试它,并且效果很好。
但是...如果 UIView 被缩放 (!=1) 并且是另一个 UIView 的子视图而不是根视图,它就不能正常工作。结果可见矩形的原点偏移了一点。如果视图在子视图中,我尝试了几种不同的方法来调整原点,但我想不出一个干净的方法来做到这一点。
我已将此方法添加到我的实用程序 UIView 类别,以及我一直在开发或获取的所有其他 "missing" UIView 方法。 (Erica Sadun 的变身术……我不配……)
这确实解决了我正在处理的问题。所以我会 post 另一个关于缩放问题的问题。
编辑: 在处理缩放问题的问答时,我也为这个问题想出了一个更好的答案:
// return the part of the passed view that is visible
- (CGRect)getVisibleRect:(UIView *)view {
// get the root view controller (and it's view is vc.view)
UIViewController *vc = UIApplication.sharedApplication.keyWindow.rootViewController;
// get the view's frame in the root view's coordinate system
CGRect rootRect = [vc.view convertRect:view.frame fromView:view.superview];
// get the intersection of the root view bounds and the passed view frame
CGRect rootVisible = CGRectIntersection(vc.view.bounds, rootRect);
// convert the rect back to the initial view's coordinate system
CGRect visible = [view convertRect:rootVisible fromView:vc.view];
return visible; // may be same as the original view frame
}