web-dev-qa-db-fra.com

Faites pivoter UIView autour de son centre en gardant sa taille

J'essaie de faire pivoter une UIView de quelques radians, mais après avoir appliqué la transformation, elle ne semble pas conserver sa taille. Quelle est la bonne façon d'y parvenir?

Voici ce que je fais et ce que je reçois (la boîte bleue avec la flèche est la vue que je tente de faire pivoter - elle devrait conserver le même aspect que la boîte rouge derrière):

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)

double rads = DEGREES_TO_RADIANS(240);
CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, rads);
self.arrowView.transform = transform;

enter image description here

Merci!

44
Diego Acosta

Vous rencontrez probablement un problème avec Autolayout. Vous avez probablement des contraintes sur la vue pivotée, épinglant celle-ci aux bords de la vue d'ensemble. Lorsque la transformation est appliquée, Autolayout met à jour la taille de la vue pour qu'elle s'adapte toujours à la vue d'ensemble. 

Vous pouvez expérimenter différentes contraintes (par exemple, épingler le centre de la vue au centre d’une autre vue et épingler la largeur et la hauteur à des valeurs constantes) ou désactiver Autolayout pour la vue pivotée, ou si elles ne fonctionnent pas Si vous préférez, utilisez une vue conteneur présentée sous Autolayout et ajoutez-y votre vue tournante sans utiliser Autolayout. 

Cela ne peut être fait que dans le code - vous pouvez soumettre des vues individuelles à Autolayout ou non en définissant translatesAutoresizingMasksIntoConstraints sur NO (Autolayout on) ou YES (Autolayout off). Vous devrez définir les masques de redimensionnement automatique appropriés si vous passez d'une vue à une autre. 

24
jrturton

J'évite d'utiliser des macros sauf si nécessaire. Cela fonctionne parfaitement bien

float degrees = 20; //the value in degrees
view.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);
44
Shaheen Ghiassy

Swift + extension sont tes amis!

// MARK: - UIView Extension -

extension UIView {

    /**
     Rotate a view by specified degrees

     - parameter angle: angle in degrees
     */
    func rotate(angle angle: CGFloat) {
        let radians = angle / 180.0 * CGFloat.pi
        let rotation = CGAffineTransformRotate(self.transform, radians);
        self.transform = rotation
    }

}

De cette façon, n'importe où dans votre code:

let view = UIView(frame: CGRectMake(0, 0, 100, 100))
view.backgroundColor = UIcolor.redColor()
view.rotate(angle: 90)
20
Luca Davanzo

La transformation CGAffineTransformRotate tourne à partir d'une transformation affine existante. Le fait que vous utilisez CGAffineTransformIdentity pourrait être le problème. Vous devez spécifier la transformation en cours de votre vue.

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
...
double rads = DEGREES_TO_RADIANS(240);
CGAffineTransform transform = CGAffineTransformRotate(self.arrowView.transform, rads);
self.arrowView.transform = transform;

Aussi, vous voudrez peut-être considérer:

self.arrowView.transform = CGAffineTransformMakeRotation(rads);

EDIT: Si vous le pouvez, partagez le type de transformation (animée/inanimée, unique/itérative) que vous souhaitez réaliser. Je crois qu'il pourrait y avoir une meilleure façon, optimisée, de faire cela.

12
n00bProgrammer

Mettez à jour la réponse de Luca Davanzo avec Swift 4:

/**
 Rotate a view by specified degrees

 - parameter angle: angle in degrees
 */
func rotate(angle: CGFloat) {
    let radians = angle / 180.0 * CGFloat.pi
    let rotation = self.transform.rotated(by: radians)
    self.transform = rotation
}
12
Bill Chan

Essayez avec ce code:

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)

double rads = DEGREES_TO_RADIANS(240);
self.arrowView.layer.transform = CATransform3DMakeRotation(rads, 0, 0, 1);
5
Abhinav

Sur Swift 3:

let degrees: CGFloat = -90
let radians = CGFloat(__sinpi(degrees.native/180.0))
view.transform = CGAffineTransform(rotationAngle: radians)

J'utilise -90 en raison de cette partie spécifique de la documentation sur la rotationAngle que vous devez transmettre à CGAffineTransform:

L'angle, en radians, selon lequel cette matrice fait pivoter la coordonnée axes du système. Dans iOS, une valeur positive indique le sens antihoraire rotation et une valeur négative spécifie la rotation dans le sens des aiguilles d'une montre.

1
Bruno Delgado

À mon avis, vous devez calculer le centre de votre triangle et effectuer une rotation autour de ce point. Maintenant, vous faites pivoter la flèche autour du centre de votre carré.

Voir: Transformation affine en une étape pour la rotation autour d'un point?

J'espère que cela vous aidera.

0
Sauvage