Как получить видимую часть UIView, которая частично панорамируется за пределы экрана? - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть UIView, который я перемещаю жестом панорамирования в сторону экрана, и теперь UIView только частично отображается на экране.Как получить CGRect, который содержит ТОЛЬКО видимую часть UIView, И, в координатах исходного представления?

Я пробовал комбинации CGRectIntersect() для прямоугольника UIView.frame и [UIScreen mainscreen].bounds прямоугольник, например:

CGRect rect = CGRectIntersection([UIScreen mainScreen].bounds,
                                 view.frame);

Мне не удалось правильно разрешить сопоставление систем координат.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

После нескольких (нескольких часов) экспериментов я пришел к следующему решению:

// 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
}
0 голосов
/ 27 сентября 2018

Сначала вам нужно перевести 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, а затем найдет пересечение.Это будет работать, даже если ваш смещенный вид вложен в несколько слоев видов.

...