我有一个UIView,可以用平移手势将其移动到屏幕的侧面,现在UIView仅部分显示在屏幕上。如何获取在原始视图的坐标中仅包含UIView可见部分和的CGRect?
我已经尝试将CGRectIntersect()
和UIView.frame
的{{1}}组合使用,像这样:
[UIScreen mainscreen].bounds
我无法正确解析匹配的坐标系。
答案 0 :(得分:1)
首先,您需要将位移视图的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的坐标系,然后找到相交处。即使您将位移视图嵌套在多层视图中,这也将起作用。
答案 1 :(得分:-1)
经过几个小时的实验,我想到了以下解决方案:
// 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,但这没有用。但是对于以根视图作为其超级视图的UIView,我得到了相反的效果。然后,经过一番摸索,我发现我必须遍历子视图的视图层次结构。
它适用于以超级视图为根视图的UIView,也适用于作为其他视图的子视图的UIView。
我通过在初始视图的这些可见矩形周围绘制边框来对其进行测试,并且效果很好。
但是...如果缩放了UIView(!= 1)以及除根视图之外的另一个UIView的子视图,它将无法正常工作。所得可见rect的原点偏移了一点。如果视图在子视图中,我尝试了几种其他方法来调整原点,但我想不出一种干净的方法。
我已将此方法以及我一直在开发或获取的所有其他“缺失的” UIView方法添加到实用程序UIView类别中。 (Erica Sadun的变换方法...我不值得...)
这确实解决了我正在研究的问题。因此,我将发布有关缩放问题的另一个问题。
编辑: 在解决扩展性问题时,我也为该问题提供了一个更好的答案:
// 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
}