Obtenga la posición de UIView con respecto a la supervista de su supervista

97

Tengo una UIView, en la que he organizado UIButtons. Quiero encontrar las posiciones de esos UIButtons.

Soy consciente de que buttons.frameme dará las posiciones, pero me dará posiciones solo con respecto a su supervisión inmediata.

¿Hay alguna forma de que podamos encontrar las posiciones de esos botones, con respecto a la supervista de supervista de UIButtons?

Por ejemplo, suponga que hay una UIView llamada "firstView".

Entonces, tengo otro UIView, "secondView". Esta "SecondView" es una subvista de "firstView".

Entonces tengo UIButton como una subvista en el "secondView".

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

Ahora, ¿hay alguna forma de que podamos encontrar la posición de ese UIButton, con respecto a "firstView"?

Shailesh
fuente

Respuestas:

192

Puedes usar esto:

C objetivo

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

Rápido

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

Referencia de la documentación:

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

mprivat
fuente
Para agregar a esto, si su vista no siempre está en la misma vista (digamos, si está usando esto en una función) puede poner '... fromView: [button superview]];'
mylogon
39

Aunque no es específico del botón en la jerarquía como se me preguntó, encontré esto más fácil de visualizar y comprender:

Desde aquí: fuente original

ingrese la descripción de la imagen aquí

ObjC:

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

Rápido:

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

Actualizado para Swift 3

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

        print(frame)
    }

ingrese la descripción de la imagen aquí

iAj
fuente
7

Marco: (X, Y, ancho, alto).

Por lo tanto, el ancho y la altura no cambiarán incluso con la vista super-super. Puede obtener fácilmente X, Y de la siguiente manera.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
fuente
Pero por qué obtengo el valor X, Y en una cantidad tan alta como cuando mi X era 0,0, entonces obtengo con sus líneas de código como; 180224 más o menos?
5

Si hay varias vistas apiladas y no necesita (o desea) conocer las posibles vistas entre las vistas que le interesan, puede hacer esto:

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

donde targetViewestaría el botón, baseViewsería el ViewController.view.
Lo que esta función está tratando de hacer es lo siguiente:
Si targetViewno tiene una supervista, se devuelve su coordenada actual.
Si targetView'sla supervista no es la vista base (es decir, hay otras vistas entre el botón y viewcontroller.view), se recupera una coordenada convertida y se pasa a la siguiente superview.
Continúa haciendo lo mismo a través de la pila de vistas que se mueven hacia baseView.
Una vez que llega al baseView, hace una última conversión y lo devuelve.
Nota: no maneja una situación en la que targetViewse coloca debajo de baseView.

Rexb
fuente
4

Extensión UIView para convertir el marco de la subvista (inspirado en la respuesta 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
fuente
2

Puede obtener fácilmente la vista super-super de la siguiente manera.

secondView -> [botón de supervista]
firstView -> [[botón de supervista] supervista]

Luego, puede obtener la posición del botón.

Puedes usar esto:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
dijo altintop
fuente
2
Agregar alguna explicación haría que esta respuesta sea más útil.
Sagar Zala