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

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


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)

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í


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;

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.


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)

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;

2
Agregar alguna explicación haría que esta respuesta sea más útil.
Sagar Zala
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.