iPhone - Obtenez la position de UIView dans toute la fenêtre UIWindow

206

La position d'un UIViewpeut évidemment être déterminée par view.centerou view.frameetc., mais cela ne renvoie que la position du UIViewpar rapport à sa vue d'ensemble immédiate.

J'ai besoin de déterminer la position du UIViewdans l'ensemble du système de coordonnées 320x480. Par exemple, si le UIViewest dans UITableViewCellsa position dans la fenêtre peut changer radicalement indépendamment de la vue d'ensemble.

Avez-vous des idées si et comment cela est possible?

À votre santé :)

Adam
la source

Réponses:

340

C'est simple:

[aView convertPoint:localPosition toView:nil];

... convertit un point de l'espace de coordonnées locales en coordonnées de fenêtre. Vous pouvez utiliser cette méthode pour calculer l'origine d'une vue dans l'espace fenêtre comme ceci:

[aView.superview convertPoint:aView.frame.origin toView:nil];

Edit 2014: En regardant la popularité du commentaire de Matt__C, il semble raisonnable de souligner que les coordonnées ...

  1. ne changez pas lors de la rotation de l'appareil.
  2. ont toujours leur origine dans le coin supérieur gauche de l'écran sans rotation.
  3. sont les coordonnées de la fenêtre : Le système de coordonnées est défini par les limites de la fenêtre. Les systèmes de coordonnées de l'écran et de l'appareil sont différents et ne doivent pas être mélangés avec les coordonnées de la fenêtre.
Nikolai Ruhe
la source
génial :) Je pensais que cela devrait être simple, mais j'avais l'impression que la pomme ne serait pas si facile ... eh bien, ils l'ont fait. merci
Lior Frenkel
41
Sachez que spécifier nil dans le paramètre toView vous donne les coordonnées de l'appareil, ce qui ne sera pas ce que vous voulez si vous n'êtes pas en orientation portrait. Voir convertpointtoview-in-landscape-mode-giveing-false-values
Matt__C
2
Cette méthode revenait sans cesse aView.frame.originpour moi. Il m'a fallu un peu de temps pour réaliser que la vue d'ensemble de ma vue n'avait pas de vue d'ensemble en elle-même.
Dan Abramov
3
Si votre superView n'avait pas de superView, votre vue ne devrait pas du tout être vue
user4951
17
En adaptant la solution liée @Matt__C à votre cas, cela deviendrait:[view.superview convertPoint:view.frame.origin toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]
Ghigo
49

Swift 5, Swift 4 :

let globalPoint = aView.superview?.convert(aView.frame.origin, to: nil)
Yuchen Zhong
la source
33

Swift 3, avec extension:

extension UIView{
    var globalPoint :CGPoint? {
        return self.superview?.convert(self.frame.origin, to: nil)
    }

    var globalFrame :CGRect? {
        return self.superview?.convert(self.frame, to: nil)
    }
}
Mohsenasm
la source
30

Dans Swift:

let globalPoint = aView.superview?.convertPoint(aView.frame.origin, toView: nil)
Shlomi Schwartz
la source
9

Voici une combinaison de la réponse de @Mohsenasm et d'un commentaire de @Chigo adopté par Swift

extension UIView {
    var globalFrame: CGRect? {
        let rootView = UIApplication.shared.keyWindow?.rootViewController?.view
        return self.superview?.convert(self.frame, to: rootView)
    }
}
Vlad Spreys
la source
simple et sympa!
nastassia