Ottieni la posizione di UIView rispetto alla superview della sua superview


97

Ho una UIView, in cui ho organizzato UIButtons. Voglio trovare le posizioni di quei pulsanti UIB.

Ne sono consapevole buttons.frame mi darà le posizioni, ma mi darà posizioni solo rispetto alla sua immediata supervisione.

C'è un modo per trovare le posizioni di quei pulsanti, rispetto alla superview di UIButtons superview?

Ad esempio, supponiamo che ci sia UIView denominato "firstView".

Quindi, ho un altro UIView, "secondView". Questa "SecondView" è una sottoview di "firstView".

Poi ho UIButton come sottoview sulla "secondView".

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

Ora, c'è un modo per trovare la posizione di quel UIButton, rispetto a "firstView"?

Risposte:


192

Puoi usare questo:

Obiettivo-C

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

Swift

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

Riferimento alla documentazione:

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


Per aggiungere a questo, se la tua vista non è sempre nella stessa vista (ad esempio, se stai usando questo in una funzione) puoi mettere '... fromView: [button superview]];'
mylogon

39

Sebbene non sia specifico per il pulsante nella gerarchia come richiesto, l'ho trovato più facile da visualizzare e capire:

Da qui: fonte originale

inserisci qui la descrizione dell'immagine

ObjC:

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

Swift:

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

20

Aggiornato per Swift 3

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

        print(frame)
    }

inserisci qui la descrizione dell'immagine


7

Cornice: (X, Y, larghezza, altezza).

Quindi larghezza e altezza non cambieranno nemmeno rispetto alla vista super super. Puoi facilmente ottenere X, Y come segue.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;

Ma perché ottengo il valore X, Y in quantità così elevate come quando la mia X era 0,0, allora sto ottenendo con le tue linee di codice come; 180224 o giù di lì?

5

Se sono presenti più visualizzazioni impilate e non è necessario (o non si desidera) conoscere eventuali visualizzazioni tra le visualizzazioni a cui si è interessati, è possibile eseguire questa operazione:

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

dove targetViewsarebbe il pulsante, baseViewsarebbe il ViewController.view.
Ciò che questa funzione sta cercando di fare è il seguente:
Se targetViewnon ha una super vista, viene restituita la coordinata corrente.
Se la targetView'ssuper view non è baseView (cioè ci sono altre viste tra il pulsante e viewcontroller.view), una coordinata convertita viene recuperata e passata alla successiva superview.
Continua a fare lo stesso attraverso la pila di viste che si spostano verso baseView.
Una volta raggiunto baseView, esegue un'ultima conversione e la restituisce.
Nota: non gestisce una situazione in cui targetViewè posizionato sotto il baseView.


4

Estensione UIView per convertire il frame della sottoview (ispirato alla risposta di @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

Puoi facilmente ottenere la super-super vista come segue.

secondView -> [pulsante superview]
firstView -> [[button superview] superview]

Quindi, puoi ottenere la posizione del pulsante ..

Puoi usare questo:

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

2
Aggiungere qualche spiegazione renderebbe questa risposta più utile.
Sagar Zala
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.