Obtenir la position de UIView par rapport à la supervision de sa supervision

97

J'ai un UIView, dans lequel j'ai arrangé des UIButtons. Je veux trouver les positions de ces UIButtons.

Je sais que buttons.framecela me donnera les postes, mais cela ne me donnera des postes que par rapport à sa supervision immédiate.

Existe-t-il un moyen de trouver les positions de ces boutons, par rapport au superview de UIButtons superview?

Par exemple, supposons qu'il y ait UIView nommé "firstView".

Ensuite, j'ai un autre UIView, "secondView". Ce "SecondView" est une sous-vue de "firstView".

Ensuite, j'ai UIButton comme sous-vue sur le "secondView".

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

Maintenant, y a-t-il un moyen de trouver la position de cet UIButton, par rapport à "firstView"?

Shailesh
la source

Réponses:

192

Vous pouvez utiliser ceci:

Objectif c

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

Rapide

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

Référence de la documentation:

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

mprivat
la source
Pour ajouter à cela, si votre vue n'est pas toujours dans la même vue (par exemple, si vous l'utilisez dans une fonction), vous pouvez mettre '... fromView: [button superview]];'
mylogon
39

Bien que cela ne soit pas spécifique au bouton dans la hiérarchie, comme demandé, j'ai trouvé cela plus facile à visualiser et à comprendre:

D'ici: source originale

entrez la description de l'image ici

ObjC:

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

Rapide:

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

Mis à jour pour Swift 3

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

        print(frame)
    }

entrez la description de l'image ici

iAj
la source
7

Cadre: (X, Y, largeur, hauteur).

Par conséquent, la largeur et la hauteur ne changeront pas même avec la vue super-super. Vous pouvez facilement obtenir le X, Y comme suit.

X = button.frame.origin.x + [button superview].frame.origin.x;
Y = button.frame.origin.y + [button superview].frame.origin.y;
iRavi iVooda
la source
Mais pourquoi j'obtiens la valeur X, Y en quantité si élevée, comme lorsque mon X était 0,0, alors je reçois vos lignes de code comme; 180224 environ?
5

S'il y a plusieurs vues empilées et que vous n'avez pas besoin (ou ne voulez) pas connaître les vues possibles entre les vues qui vous intéressent, vous pouvez faire ceci:

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

targetViewserait le bouton, baseViewserait le ViewController.view.
Ce que cette fonction essaie de faire est ce qui suit:
Si targetViewn'a pas de super vue, sa coordonnée actuelle est renvoyée.
Si la targetView'ssuper vue n'est pas la baseView (c'est-à-dire qu'il y a d'autres vues entre le bouton et viewcontroller.view), une coordonnée convertie est récupérée et transmise à la suivante superview.
Il continue à faire de même à travers la pile de vues se déplaçant vers la baseView.
Une fois qu'il atteint le baseView, il effectue une dernière conversion et le renvoie.
Remarque: il ne gère pas une situation où targetViewest positionné sous le baseView.

Rexb
la source
4

Extension UIView pour convertir le cadre de la sous-vue (inspiré de @Rexb answer).

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
la source
2

Vous pouvez facilement obtenir la vue super-super comme suit.

secondView -> [bouton
superview ] firstView -> [[bouton superview] superview]

Ensuite, vous pouvez obtenir la position du bouton.

Vous pouvez utiliser ceci:

xPosition = [[button superview] superview].frame.origin.x;
yPosition = [[button superview] superview].frame.origin.y;
dit altintop
la source
2
L'ajout d'explications rendrait cette réponse plus utile.
Sagar Zala du