web-dev-qa-db-fra.com

Obtenez la position d'UIView par rapport à sa superview

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

Je suis conscient que buttons.frame me donnera les positions, mais il ne me donnera des positions que par rapport à son aperçu immédiat. 

Existe-t-il un moyen de trouver la position de ces boutons, en respectant le superview de UIButtons superview? 

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

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

Ensuite, j'ai UIButton en tant que sous-vue sur le "secondView". 

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

Maintenant, est-il possible de trouver la position de cet UIButton par rapport à "firstView"?

65
Shailesh

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

147
mprivat

Mis à jour pour Swift 3

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

        print(frame)
    }

 enter image description here

15
iajmeri43

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

 enter image description here

ObjC:

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

Rapide:

let point = subview1.convert(subview2.frame.Origin, to: viewControll.view)
13
Vlad

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

Par conséquent, la largeur et la hauteur ne changeront pas même en super vue. 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;
6
iRavi iVooda

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

secondView -> [bouton superview]
firstView -> [[button 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;
1
said altintop

Si plusieurs vues sont 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 procéder comme suit:

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

où targetView serait le bouton, baseView serait le ViewController.view .
Ce que cette fonction essaie de faire est la suivante:
Si targetView n'a pas de super vue, ses coordonnées actuelles sont retournées.
Si la super vue de targetView n’est pas la baseView (c’est-à-dire qu’il existe d’autres vues entre le bouton et viewcontroller.view), une coordonnée convertie est extraite et passée au survol suivant. 
Il continue à faire de même avec la pile de vues se déplaçant vers la baseView. 
Une fois qu'il a atteint le baseView, il effectue une dernière conversion et le renvoie.
Remarque: il ne gère pas une situation où targetView est positionné sous le baseView.

0
Rexb

Extension UIView pour la conversion du cadre de la sous-vue (inspirée de la réponse @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)
0
boro