Отримайте позицію UIView щодо супервигляду його супервізу


97

У мене є UIView, в якому я розташував кнопки UIB. Я хочу знайти позиції цих кнопок UIB.

Я усвідомлюю, що buttons.frameце дасть мені позиції, але це дасть мені позиції лише стосовно безпосереднього супервізу.

Чи можна якось знайти позиції цих кнопок, з повагою до суперпрегляду UIButtons superview?

Наприклад, припустимо, існує UIView з назвою "firstView".

Потім у мене є інший UIView, "secondView". Цей "SecondView" є підпрограмою "firstView".

Тоді я маю UIButton як підпрогляд на "secondView".

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

Тепер, чи можна якось знайти позицію цієї кнопки UIB щодо "firstView"?

Відповіді:


192

Ви можете використовувати це:

Завдання-C

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

Стрімкий

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

Довідкова документація:

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


Щоб додати до цього, якщо ваш вигляд не завжди знаходиться в одному поданні (скажімо, якщо ви використовуєте це у функції), ви можете поставити '... fromView: [кнопка перегляду]];'
mylogon

39

Хоча це не специфічно для кнопки в ієрархії, як я запитував, мені було легше це уявити та зрозуміти:

Звідси: першоджерело

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

ObjC:

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

Стрімкий:

let point = subview1.convert(subview2.frame.origin, to: viewControll.view)

20

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

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

        print(frame)
    }

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


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;

Але чому я отримую значення 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супер-подання не є baseView (тобто між кнопкою та є інші види viewcontroller.view), перетворена координата отримується і передається наступному superview.
Він продовжує робити те саме через стек переглядів, що рухається до baseView.
Після досягнення значення baseViewвін виконує останнє перетворення і повертає його.
Примітка: він не обробляє ситуацію, коли targetViewрозміщується під baseView.


4

Розширення UIView для перетворення кадру підвиду (натхненний відповіддю @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 -> [перегляд кнопки [superview]

Потім, Ви можете отримати положення кнопки ..

Ви можете використовувати це:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;

2
Додавши якесь пояснення, ця відповідь стане більш корисною.
Сагар Зала,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.