Obter a posição do UIView em relação ao superview de seu superview

97

Eu tenho um UIView, no qual arranjei UIButtons. Eu quero encontrar as posições desses UIButtons.

Estou ciente de que buttons.frameisso me dará as posições, mas isso me dará posições apenas no que diz respeito à sua supervisão imediata.

Existe alguma maneira de encontrarmos as posições desses botões, com respeito ao superview do UIButtons superview?

Por exemplo, suponha que haja UIView denominado "firstView".

Então, eu tenho outro UIView, "secondView". Esta "SecondView" é uma subvisualização de "firstView".

Então eu tenho UIButton como uma subvisualização no "secondView".

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

Agora, há alguma maneira de encontrarmos a posição desse UIButton, em relação a "firstView"?

Shailesh
fonte

Respostas:

192

Você pode usar isto:

Objective-C

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

Rápido

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

Referência da documentação:

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

mprivat
fonte
Para adicionar a isso, se sua visão não estiver sempre na mesma visão (digamos, se você estiver usando isso em uma função), você pode colocar '... fromView: [botão superview]];'
mylogon de
39

Embora não seja específico para o botão na hierarquia, conforme solicitado, achei mais fácil de visualizar e entender:

Daqui: fonte original

insira a descrição da imagem aqui

ObjC:

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

Rápido:

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

Atualizado para Swift 3

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

        print(frame)
    }

insira a descrição da imagem aqui

iAj
fonte
7

Quadro: (X, Y, largura, altura).

Conseqüentemente, a largura e a altura não mudarão, mesmo em relação à super visão. Você pode obter facilmente o X, Y da seguinte forma.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
fonte
Mas por que estou obtendo o valor X, Y em uma quantidade tão alta como quando meu X era 0,0, então estou obtendo com suas linhas de código como; 180224 ou assim?
5

Se houver várias visualizações empilhadas e você não precisar (ou desejar) saber nenhuma visualização possível entre as visualizações nas quais está interessado, você pode fazer o seguinte:

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)
}

onde targetViewestaria o botão, baseViewseria o ViewController.view.
O que esta função está tentando fazer é o seguinte:
Se targetViewnão tiver uma supervisão, sua coordenada atual será retornada.
Se targetView'sa supervisão não for baseView (ou seja, houver outras vistas entre o botão e viewcontroller.view), uma coordenada convertida é recuperada e passada para a próxima superview.
Ele continua a fazer o mesmo por meio da pilha de visualizações em direção a baseView.
Quando atinge o baseView, ele faz uma última conversão e o retorna.
Nota: ele não lida com uma situação onde targetViewestá posicionado sob o baseView.

Rexb
fonte
4

Extensão UIView para converter o quadro de subvisualização (inspirado na resposta de @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)
boro
fonte
2

Você pode obter facilmente a superexibição da seguinte forma.

secondView -> [botão superview]
firstView -> [[botão superview] superview]

Então, você pode obter a posição do botão.

Você pode usar isto:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
disse altintop
fonte
2
Adicionar alguma explicação tornaria essa resposta mais útil.
Sagar Zala