Fonix
Fonix

Reputation: 11597

iOS rotate single view on orientation change

My app is portrait mode only, but i want to be able to rotate a single UIImageView on orientation change, i can get the orientation events just fine by going

UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"orientationChanged:", name: UIDeviceOrientationDidChangeNotification, object: nil)

then in "orientationChanged:" i have the following code to rotate the image

    var o = UIDevice.currentDevice().orientation

    var angle:Double = 0;
    if (o == UIDeviceOrientation.LandscapeLeft ){angle = M_PI_2}
    else if (o == UIDeviceOrientation.LandscapeRight ){angle = -M_PI_2}
    else if (o == UIDeviceOrientation.PortraitUpsideDown ){ angle = M_PI}

    UIView.animateWithDuration(0.3, animations: { () -> Void in

        self.previewImage.transform = CGAffineTransformMakeRotation((CGFloat)(angle))

        switch(UIDevice.currentDevice().orientation)
        {

        case UIDeviceOrientation.LandscapeLeft, UIDeviceOrientation.LandscapeRight:
            println("landscape")
            self.previewImage.frame = CGRectMake(0, 0, self.previewCardContainer.bounds.size.height, self.previewCardContainer.bounds.size.width)
        default:
            self.previewImage.frame = self.previewCardContainer.bounds
        }

        self.previewImage.center = self.previewCardContainer.center

        self.previewCardContainer.layoutSubviews()
    })

previewImage is the one i want to rotate, it is contained inside a UIView called previewImageCard. now it does the rotation, but i want it to keep the shape of the container each time it rotates by 90 degrees, so effectively the width and height will swap if its in a landscape orientation, and keep the containers normal frame if its portrait.

I have tried using autolayout with this but im pretty sure that messes everything up, so in my storyboard i leave the previewImage without any constraints (just placeholder intrinsic size) and i set

previewCardContainer.setTranslatesAutoresizingMaskIntoConstraints(true) //and false doesnt seem to help

The previewImage rotates fine, but the frame doesnt update at all and i have no idea why, what could be causing the frame to not update within an animation?

ps: i dont mind answers in objective-c

Upvotes: 1

Views: 901

Answers (1)

Fonix
Fonix

Reputation: 11597

I managed to solve this with using autolayout actually, i set a width and height constraint and also a vertical and horizontal center constraint

then in my viewDidLoad i go

    previewImageHeightConstraint.constant = previewCardContainer.frame.size.height - 20
    previewImageWidthConstraint.constant = previewCardContainer.frame.size.width - 20

in my orientationChanged: method i go

func orientationChanged(notification:NSNotification){

    var o = UIDevice.currentDevice().orientation

    var angle:Double = 0;
    if (o == UIDeviceOrientation.LandscapeLeft ){angle = M_PI_2}
    else if (o == UIDeviceOrientation.LandscapeRight ){angle = -M_PI_2}
    else if (o == UIDeviceOrientation.PortraitUpsideDown ){ angle = M_PI}

    UIView.animateWithDuration(0.3, animations: { () -> Void in

        var rot = CGAffineTransformMakeRotation((CGFloat)(angle))
        self.previewImage.transform = rot

        switch(UIDevice.currentDevice().orientation)
        {

        case UIDeviceOrientation.LandscapeLeft, UIDeviceOrientation.LandscapeRight:
            self.previewImageWidthConstraint.constant = self.previewCardContainer.frame.size.height - 20
            self.previewImageHeightConstraint.constant = self.previewCardContainer.frame.size.width - 20
        default:
            self.previewImageHeightConstraint.constant = self.previewCardContainer.frame.size.height - 20
            self.previewImageWidthConstraint.constant = self.previewCardContainer.frame.size.width - 20
        }

        self.previewImage.center = self.previewCardContainer.center

        self.previewCardContainer.layoutIfNeeded()
    })
}

and this correctly rotates the image while keeping it centered and also adjusts its width and height according to its orientation. a look at the constraints in the storyboard: autolayout constraints

Upvotes: 0

Related Questions