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"?

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


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)

20

Atualizado para Swift 3

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

        print(frame)
    }

insira a descrição da imagem aqui


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;

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.


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)

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;

2
Adicionar alguma explicação tornaria essa resposta mais útil.
Sagar Zala
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.