change background image in a cell when iPhone rotates - iphone

My tableview has 4 cells, and each cells has one different picture as background.
When I rotate the iPhone, the height of the rows change, and also the pictures.
Is really easy to change picture if the position is in landscape or in portrait, but the picture change when the iPhone is already rotated, not while is rotating!
What's the problem?
For example: the iPhone is in portrait and the user rotates it in landscape.
That there is a very ugly effect, because the pictures change just when the iPhone is in landscape, and for a fraction of a second the user sees the portrait picture deformed (before that it changes).
How can I solve it?
Thanks

The easy way:
Implement willAnimateRotationToInterfaceOrientation in your view controller. Inside this method you can reorient your pictures and they'll automatically be animated. There's a short overview this and other available interface orientation methods at http://www.dizzey.com/development/ios/handling-layout-on-uiinterfaceorientation-change/
Pointlessly difficult way:
You could manually track acceleration and write your own animation blocks.
Set your view controller as a UIAccelerometerDelegate. Reference the sharedAccelerometer as follows.
accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
Then implement this delegate method. This will be run every time the accelerometer notices acceleration. Tracking acceleration in the X axis will give you landscape/portrait orientation.
#pragma mark UIAccelerometer delegate method
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
if(acceleration.x > 0.8) //landscape right
{
[UIView beginAnimations:#"text spin" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:0.2];
//do some animation to landscape right
[UIView commitAnimations];
}
if(acceleration.x < -0.8) //landscape left
{
[UIView beginAnimations:#"text spin" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:0.2];
//do some animation to landscape left
[UIView commitAnimations];
}
if(acceleration.x < 0.2 && acceleration.x > -0.2) //portrait
{
[UIView beginAnimations:#"text spin" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:0.2];
//do some animation to portrait view
[UIView commitAnimations];
}

In a situation like this, during a rotation I tend to just use the .hidden property on elements (myObject.hidden = YES) and then restore them when the rotation is complete.
I imagine your picture frames have more room in landscape view - another suggestion if this is true, is to keep them the same size in both orientations, then you wouldn't need to hide them during a rotation, for example.
Hope this helps!

Related

How to impelment Phone call animation like iPhone's default Phone application does?

My application has VOIP calling. In that I want to implement animation like iPhone's default Phone application does when User Clicks on Call button on dial Pad and animation that is done on End call button.
I have researched alot about this but haven't find anything yet. Any help will be appreciated on this topic.
Right now I have implemented scaling animation like below:
- (void)animateFadingOut{
self.view.transform = CGAffineTransformMakeScale(1.00, 1.00);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[self performSelector:#selector(push) withObject:nil afterDelay:0.35];
self.view.transform = CGAffineTransformMakeScale(0.00, 0.00);
//set transformation
[UIView commitAnimations];
}
- (void)push
{
self.view.transform = CGAffineTransformMakeScale(1.00, 1.00);
// push navigation controloller
CallViewController *objCallViewController = [[CallViewController alloc] initWithNibName:#"CallViewController_iPhone" bundle:nil];
[self setHidesBottomBarWhenPushed:YES];
[self.navigationController pushViewController:objCallViewController animated:NO];
[objCallViewController release];
[self setHidesBottomBarWhenPushed:NO];
[[AppDelegate shared] setTabHidden:TRUE];
}
But It is not giving me exact animation that default Phone application has
Here is what I might try if I was trying to create animations.
CGRect movementFrame = self.view.frame;
//Make position and size changes as needed to frame
movementFrame.origin.x = 0;
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
/*
Animation you want to commit go here
Apply movementFrame info to the frame
of the item we want to animate
*/
//If you wanted a fade
self.view.alpha = !self.view.alpha //Simply says I want the reverse.
self.view.frame = movementFrame;
//Example of what you could do.
self.view.transform =CGAffineTransformMakeScale(1.00, 1.00);
} completion:^(BOOL finished) {
//Things that could happen once the animation is finished
[self push];
}];
This has not been tested for your case. Therefore I am also not sure if it will help you, but hopefully it will. Good luck to you.
*Edit*
So I reviewed the animation on an iPhone and it appears to me to be a series of animations happening at once.
You have what I presume to be the UIActionSheet animating down.
The top section overlay sliding up its y-axis.
Then you have, which I haven't mastered yet, a split in the back view that animates its x-axis in opposite directions which cause the split.
Finally you have the new view scale up to take frame for the effect.
I can't say 100% this how they have done it, however if I was going to attempt to recreate this, I would likely start here.
Hello there so after just quickly coming up with an animation I got pretty close it could use some tweaks.
It took me three views to do a
topView, bottomView, and backView.
Also took into account the view that you would be loading in. viewToLoadIn
`-(void)animation{
CGRect topMovementFrame = self.topView.frame; //Set dummy frame to modify
CGRect bottomViewFrame = self.bottomview.frame;
topMovementFrame.origin.y = 0 - self.topView.frame.size.height; //modify frame's yAxis so that the frame sits above the screen.
bottomViewFrame.origin.y = self.view.frame.size.height; //modify frame's yAxis to the it will sit at the bottom of the screen.
[self.viewToLoadIn setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
//Animation
self.topView.frame = topMovementFrame; //Commit animations
self.bottomview.frame = bottomViewFrame;
self.backView.alpha = !self.backView.alpha;
self.backView.transform = CGAffineTransformMakeScale(100, 100);
self.viewToLoadIn.transform = CGAffineTransformMakeScale(2.0, 3.0);
*MAGIC*
} completion:^(BOOL finished) {
//Completion
//Clean up your views that you are done with here.
}];
}`
So then When they pressed the button I had setup this animation would happen.
Also at first I thought that the setup might contain a UIActionStyleSheet. which it still might but this is a pretty handy built in functionality. But the fact that you can interact with the screen lead me to think a custom view. It would be easier in my opinion.
I hope this helps you even if it just a little bit.
Take care ^^

Rotating a UIAlertView

I've created a custom UIAlertView (by subclassing it and messing around with its show function) that has some custom subviews and is of non-standard size.
It works ok when I create and display it, however, when the device is rotated, the alert rotates and then returns to its default size.
Any ideas what functions to override - or should I tweak the UIViewController?
thanks,
Peter
Not sure if force rotating the UIAlertView fits the Apple GUI guidelines, but you can rotate it by defining the status bar (status bar and UIAlertView sticks together)
application.statusBarOrientation = UIInterfaceOrientationLandscapeRight;
application.statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
But UIAlertView is a UIView just like many others, so try this :
- (void)didPresentAlertView:(UIAlertView *)alertView
{
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.1];
alertView.transform = CGAffineTransformRotate(alertView.transform, degreesToRadian(90));
[UIView commitAnimations];
}

Difficulties in detecting touch while animating an imageview

I am trying to animate an image using following code:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:40];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
CGAffineTransform rotate = CGAffineTransformMakeRotation(0.0);
CGAffineTransform moveRight = CGAffineTransformMakeTranslation(0, 0);
CGAffineTransform firstHalf = CGAffineTransformConcat(rotate, moveRight);
CGAffineTransform zoomIn = CGAffineTransformMakeScale(2,2);
CGAffineTransform transform = CGAffineTransformConcat(zoomIn, firstHalf);
fimage.transform = transform;
[UIView commitAnimations];
I have UIScrollView which has one subview UIImageView and fimage is that UIImageView. But when i try to detect the touch on it i am not able to do that. Can any one help me? Is is possible to detect touches on UIScrollView.
The main application is to display images in panning and when user clicks on it the web page containing that image should be loaded in next web view.
How can I achieve this?
I tested your code and it seems to be working without hiccups. It is likely that the image view object has its userInteractionEnabled set to NO. Set it to YES to make touches work.
Check this to see how you can load images in UIWebView object. As for panning, you should try out the UIPanGestureRecognizer if you aren't already.

UISegmentedControl customization

I have a UISegmentedControl on one of my pages. I want an editbox to appear when a segment is clicked right below the clicked segment. I would like it to be animated (slide in or something)
Is this possible? What would be the best way to do this?
Damn.I forgot to mention all this action is going to occur within a cell and not a simple view.
You may try UIView animation.
Firstly set your editbox (UITextView I guess ??) to x coordinate 320 (so it will not appear).
Secondly when user hit the segmented control just translate your UITextView using UIView animation :
[UIView beginAnimation:nil context:nil];
[UIView setAnimationDuration: 1.0];
CGAffineTransform trans = CGAffineTransformMakeTranslation(-320, 0);
self.view.transform = trans;
[UIView commitAnimations];
Hope it will help you ;) .
Ok, so I will try to be more precise, I guess you are using Interface Builder ?
So you have to "link" an action to you UISegmentedController, so in your class write this method :
-(IBAction) translateMyView
{
//If the first segment is selected do translation of the cellView
if(yourSegmentedController.selectedSegmentIndex == 0)
{
[UIView beginAnimation:nil context:nil];
[UIView setAnimationDuration: 1.0];
//This will translate the view to its position from its position -320 px
CGAffineTransform trans = CGAffineTransformMakeTranslation(-320, 0);
//Replace self.view with the view you want to translate.
self.view.transform = trans;
[UIView commitAnimations];
}
else if(yourSegementedController.selectedSegmentIndex ==1)
{
//Do same thing that above but with another view
}
}
So this is the action that occure when you select an index in your segmentedController.
What you have to do is linking this action to your UISegmentedController in Interface Builder.
Hope it will be helpfull ;-)

How to keep image from autorotating?

I've got an UIImageView as a background image for my application, which, like a helicopter in distress, autorotates. The problem is when the orientation autorotates my image gets shifted all over the place and I don't like it. Since it's a simple texture I figure the user would prefer to have it stay in its place, and not autorotate. What I mean by this is that I would like the image to stay full screen, and when the user rotates the phone the image is just rotated 90 degrees so it appears the image is static with the phone, not the rest of the application.
You can try implementing the willAnimateRotationToInterfaceOrientation:duration: method in your view controller and rotating the UIImageView in the opposite direction.
The code below is from the top of my head, I can't guarantee that it will work:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
CGFloat angle = M_PI/2; // Figure out the proper angle
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
imageview.transform = CGAffineTransformMakeRotation(angle);
[UIView commitAnimations];
}
I suggest to rotate your image in an image-editing-software and load it dynamically. This is far, far easier to do, than messing around with the angles (and also the code is easier to read).
Like this:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
myBackground.image = [UIImage imageNamed:#"bg.jpg"];
} else { // landscape view
myBackground.image = [UIImage imageNamed:#"bg_landscape.jpg"];
}
}