Получить позицию UIView относительно супервизора его супервизора

99

У меня есть UIView, в котором я расположил UIButtons. Я хочу найти позиции этих UIButtons.

Я знаю, что buttons.frameэто даст мне позиции, но это даст мне позиции только в отношении своего непосредственного руководства.

Есть ли способ найти положение этих кнопок с учетом супервизора UIButtons?

Например, предположим, что существует UIView с именем «firstView».

Затем у меня есть еще один UIView, «secondView». Этот «SecondView» является подвидом «firstView».

Затем у меня есть UIButton в качестве подпредставления "secondView".

->UIViewController.view
--->FirstView A
------->SecondView B
------------>Button

Теперь, есть ли способ найти положение этого UIButton по отношению к "firstView"?

Шайлеш
источник

Ответы:

197

Вы можете использовать это:

Цель-C

CGRect frame = [firstView convertRect:buttons.frame fromView:secondView];

Swift

let frame = firstView.convert(buttons.frame, from:secondView)

Ссылка на документацию:

https://developer.apple.com/documentation/uikit/uiview/1622498-convert

mprivat
источник
Чтобы добавить к этому, если ваше представление не всегда находится в одном и том же представлении (скажем, если вы используете это в функции), вы можете поместить '... fromView: [button superview]];'
mylogon
42

Хотя это не относится к кнопке в иерархии, как я просил, мне было легче визуализировать и понять:

Отсюда: первоисточник

введите описание изображения здесь

ObjC:

CGPoint point = [subview1 convertPoint:subview2.frame.origin toView:viewController.view];

Swift:

let point = subview1.convert(subview2.frame.origin, to: viewControll.view)
Влад
источник
21

Обновлено для Swift 3

    if let frame = yourViewName.superview?.convert(yourViewName.frame, to: nil) {

        print(frame)
    }

введите описание изображения здесь

iAj
источник
7

Рамка: (X, Y, ширина, высота).

Следовательно, ширина и высота не изменятся даже при супер-супер-просмотре. Вы можете легко получить X, Y следующим образом.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
источник
Но почему я получаю значение X, Y в таком большом количестве, например, когда мой X был 0,0, тогда я получаю с вашими строками кода как; 180224 или около того?
5

Если имеется несколько представлений в стеке, и вам не нужно (или вы хотите) знать какие-либо возможные представления между интересующими вас представлениями, вы можете сделать это:

static func getConvertedPoint(_ targetView: UIView, baseView: UIView)->CGPoint{
    var pnt = targetView.frame.origin
    if nil == targetView.superview{
        return pnt
    }
    var superView = targetView.superview
    while superView != baseView{
        pnt = superView!.convert(pnt, to: superView!.superview)
        if nil == superView!.superview{
            break
        }else{
            superView = superView!.superview
        }
    }
    return superView!.convert(pnt, to: baseView)
}

где targetViewбудет кнопка, baseViewбудет ViewController.view.
Эта функция пытается сделать следующее:
если targetViewнет супер-представления, возвращается текущая координата.
Если targetView'sсуперпредставление не является базовым (т.е. между кнопкой и есть другие представления viewcontroller.view), преобразованная координата извлекается и передается следующему superview.
Он продолжает делать то же самое через стек представлений, движущихся к baseView.
Как только он достигает baseView, он выполняет последнее преобразование и возвращает его.
Примечание: он не обрабатывает ситуацию, когда targetViewнаходится под baseView.

Rexb
источник
4

Расширение UIView для преобразования кадра subview (вдохновлено ответом @Rexb).

extension UIView {

    // there can be other views between `subview` and `self`
    func getConvertedFrame(fromSubview subview: UIView) -> CGRect? {
        // check if `subview` is a subview of self
        guard subview.isDescendant(of: self) else {
            return nil
        }

        var frame = subview.frame
        if subview.superview == nil {
            return frame
        }

        var superview = subview.superview
        while superview != self {
            frame = superview!.convert(frame, to: superview!.superview)
            if superview!.superview == nil {
                break
            } else {
                superview = superview!.superview
            }
        }

        return superview!.convert(frame, to: self)
    }

}

// usage:
let frame = firstView.getConvertedFrame(fromSubview: buttons.frame)
боро
источник
2

Вы можете легко получить супер-супер-вид следующим образом.

secondView -> [супервизор кнопки]
firstView -> [[супервизор кнопки] супервизор]

Затем вы можете узнать положение кнопки.

Вы можете использовать это:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
сказал Алтинтоп
источник
2
Добавление некоторых пояснений сделало бы этот ответ более полезным.
Сагар Зала