После нескольких (нескольких часов) экспериментов я пришел к следующему решению:
// 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 с корневым представлением в качестве их суперпредставления.Затем, после некоторого разговора, я понял, что мне нужно перемещаться по иерархии представлений для подпредставлений.
Это работает для UIViews, где суперпредставление является корневым представлением, а также для UIViews, которые являются подпредставлениями других представлений.
Я проверил его, нарисовав границы вокруг этих видимых линий на начальных представлениях, иэто работает отлично.
НО ... это НЕ работает правильно, если масштабируется UIView (! = 1) И подпредставление другого UIView, кроме корневого представления.Начало результирующего видимого прямоугольника смещено на бит.Я попробовал несколько разных способов отрегулировать источник, если представление находится в подпредставлении, но я не мог найти чистый способ сделать это.
Я добавил этот метод в свою служебную категорию UIView, а такжесо всеми другими «отсутствующими» методами UIView, которые я разрабатывал или приобретал.(Методы преобразования Эрики Садун ... Я не достоин ...)
Это действительно решает проблему, над которой я работал.Поэтому я опубликую еще один вопрос, касающийся проблемы масштабирования.
РЕДАКТИРОВАТЬ: Работая над вопросом и ответом на проблему масштабирования, я также нашел лучший ответ на этот вопрос:
// 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
}