I'm trying to animate a UIView to slide left and right. What I've tried is to take a screenshot of the current view, than replace the view with the screenshot while updating the contents of the view offscreen, then doing the animation. But the screenshot isn't showing up on the screen. It's just black until the original view slides back onto the screen. Here's the code I'm using:
UIGraphicsBeginImageContext(self.view.window.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)];
iv.image = image;
[self.view.window insertSubview:iv aboveSubview:self.view];
self.view.frame = CGRectMake(-self.view.frame.size.width, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
[UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
iv.frame = CGRectMake(self.view.frame.size.width*2, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
[self loadData];
self.view.frame = CGRectMake(0, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
} completion:NULL];
[iv removeFromSuperview];
[iv release];
I found the problem. I just had to do [iv removeFromSuperview]; in the completion block. Now it's working.
Usually you need just one window in your app, the one containing all your views, so self.view.window is not a good approach, I think...
If I've got what you're trying to achieve, maybe a container view could be the right solution.
For example, supposing you are working on an iPhone:
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 960.0f, 480.0f)];
firstView.frame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
secondView.frame = CGRectMake(320.0f, 0.0f, 320.0f, 480.0f);
thirdView.frame = CGRectMake(640.0f, 0.0f, 320.0f, 480.0f);
[containerView addSubview:firstView];
[containerView addSubview:secondView];
[containerView addSubview:thirdView];
Now you have your containerView containing three views. Move your containerView left or right to show the view you like and to hide the other two views, then update the views that are out of the screen.
Another approach could be using UIScrollView as containerView.
Hope this helps...
EDIT: I've misunderstood your question, sorry.
Next try...
When you add your screenshot, you add it on the right of the screen (offscreen)
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)];
iv.image = image;
[self.view.window insertSubview:iv aboveSubview:self.view];
Then you move you original view on the left (offscreen)
self.view.frame = CGRectMake(-self.view.frame.size.width, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
But you don't show your screenshot, so the view is blank.
I think you have to change this
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)];
To this
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)];
Or you can add an animation to show it from the right.
Related
In my app I want to launch UIViewController from top to bottom.So from FirstViewController I am launching MyWebViewController(which I need to animate) as follows:
MyWebViewController *theWebViewController = [[MyWebViewController alloc] initWithFrame:self.view.bounds];
[self.view addSubview:theWebViewController.view];
and In loadView of MyWebViewController I am assigning frame to view as follows;
- (void)loadView
{
CGRect theFrame;
theFrame = CGRectMake(0.0, 20.0, mFrame.size.width, 0.0);
UIView *view = [[UIView alloc] init];
view.frame = theFrame;
self.view = view;
[view release];
}
and In viewDidLoad I am changing the frame as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
[UIView beginAnimations:#"animateView" context: nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.5];
self.view.frame = CGRectMake(0.0, 20.0, mFrame.size.width, mFrame.size.height-20.0);
[UIView commitAnimations];
}
But the animation is not happening.I even tried this code to animate from bottom to top and it is working fine but vice-versa not working.Please can anyone tell me where I am doing wrong and how I can achieve?
Thanks in advance!
I wouldn't think to set the height to 0. Instead:
- (void)loadView
{
CGRect theFrame;
theFrame = CGRectMake(0.0, -mframe.size.height + 20, mFrame.size.width, m.frame.size.height - 20);
UIView *view = [[UIView alloc] init];
view.frame = theFrame;
self.view = view;
[view release];
}
You want to set the frame above and out of the view when you add it. Then move it into place in the animation.
I have an Advertisement UIViewController class that contains the following code. The frame is the exact dimension of the image. When it animates down I want it to disappear at the 76.0 point. I made the UIViewController's frame the same size as the image too, but it doesn't obscure any of the image when it slides down.
How do I make it so that I cannot see the uiimageview when it leaves the UIViewController frame?
-(void)viewDidLoad{
UIImageView *ad = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 76.0)];
ad.image = [UIImage imageNamed:#"advertisement.jpg"];
[self.view addSubview:ad];
[ad release];
[UIView animateWithDuration:1.0 //animate the content offset
delay:6.0
options:UIViewAnimationCurveEaseIn
animations:^{
ad.frame = CGRectMake(0.0, 152.0, 320.0, 76.0); }
completion:^(BOOL finished){
}
];
}
Appdelegate:
Advertisement *theAdView = [[Advertisement alloc] init];
theAdView.view.frame = CGRectMake(0.0, self.window.frame.size.height-120.0, 320.0, 76.0);
[self.window addSubview:theAdView.view];
Set the clipsToBounds property on the view (of the viewcontroller) to YES. Subviews of the view will then be drawn only within the bounds of the view.
UIView documentation
This is follower question of Move image from left to right
I have used this code for moving image from left to right, and write some code in touchBegan to stop this animation when touch on this image .But its not working during animation. when the animation end then if touch on image then this touchBegan is call.
My requirement is, during animation if image is touched then touchBegan should be execute.
UIImage *image = [UIImage imageNamed:#"PG05(REV).jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(-1024, 0, 1024, 768);
[self.view addSubview:imageView];
[imageView release]; //Your imageView is now retained by self.view
//Animation
[UIView animateWithDuration:10.0
animations:^(void) {
imageView.frame = CGRectMake(0, 0, 1024, 768);
}];
Please help me out.
You probably need this method -animateWithDuration:delay:options:animations:completion:. Replace current method with
[UIView animateWithDuration:10.0
delay:0.0
options: UIViewAnimationOptionAllowUserInteraction
animations:^{
imageView.frame = CGRectMake(0, 0, 1024, 768);
}
completion:nil];
This should enable touches during the animation.
I am displaying two images in my iPhone app, one on top, one on the bottom. They cover the entire screen. The user, with a swipe gesture, can change either of the images, depending on where the swipe started.
I want the image to change with an animated transition. It currently works without animation, or with the entire screen transitioning. Is it possible to make the transition occur over part of the screen?
I load the images for the first time (in viewDidLoad) thus:
// top image
UIImage *topImage = [UIImage imageNamed:#"top1.png"];
CGRect topframe = CGRectMake(0.0f, 0.0f, 320.0f, 240.0f);
UIImageView *topView = [[UIImageView alloc] initWithFrame:topframe];
topView.image = topImage;
[self.view addSubview:topView];
[topView release];
// bottom image
UIImage *bottomImage = [UIImage imageNamed:#"bottom1.png"];
CGRect bottomframe = CGRectMake(0.0f, 240.0f, 320.0f, 240.0f);
UIImageView *bottomView = [[UIImageView alloc] initWithFrame:bottomframe];
bottomView.image = bottomImage;
[self.view addSubview:bottomView];
[bottomView release];
When I detect a swipe, and detect which of the two images are to be changed, I call a routine like this one:
- (void)changeTopImage:(NSString *)newImage {
UIImage *topImage = [UIImage imageNamed:newImage];
CGRect topframe = CGRectMake(0.0f, 0.0f, 320.0f, 240.0f);
UIImageView *topView = [[UIImageView alloc] initWithFrame:topframe];
topView.image = topImage;
[self.view addSubview:topView];
[topView release];
}
Essentilly, I'm continually loading images on top of each other. Is that the best way to do it, especially in terms of memory management?
Everything else I've tried, using techniques such as below, make the entire screen transition:
[UIView beginAnimations:nil context:nil];
...
[UIView commitAnimations];
Thanks for any leads on which way I should be going on this.
well, an easy way could be this (repeat for the bottomImage):
don't release topView when you load it the first time in your method,
but declare it in your .h file,
and use a tempView too:
#interface YourClass: UIViewController{
UIImageView *topView;
UIImageView *tempView;
}
this way you can call them to move them and remove them when you load a new image
then in .m:
EDIT: some correction (see coco's comments):
[a] [b] line 4 = [c] line 11:
- (void)changeTopImage:(NSString *)newImage {
UIImage *topImage = [UIImage imageNamed:newImage];
//CGRect topframe = CGRectMake(0.0f, 0.0f, (320.0f + 320), 240.0f);
CGRect topframe = CGRectMake((0.0f + 320), 0.0f, 320.0f, 240.0f);
tempView = [[UIImageView alloc] initWithFrame:topframe];
//topView.image = topImage;
tempView.image = topImage;
[self.view addSubview:tempView];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView beginAnimations:#"animation" context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
tempView.center = topView.center;
// do this to push old topView away, comment next line if wanna new image just cover it
//topView.center = CGPointMake(topView.x - 320, topView.y);
topView.center = CGPointMake(topView.center.x - 320, topView.center.y);
// call a method when animation has finished:
[UIView setAnimationDidStopSelector:#selector(endOfAnimation:finished:context:)];
[UIView commitAnimations];
}
- (void)endOfAnimation:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[topView removeFromSuperview];
topView = tempView;
[tempView release];
tempView = nil;
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
- (void)dealloc {
if (tempView != nil) {
[tempView release];
}
[topView release];
[super dealloc];
}
I have a UIScrollView which has a UIView embedded in it. It have 2 buttons "scroll" and "unscroll".On clicking the "scroll" button, my scrollview scroll up from the bottom of the parent view. Everything works fine until here but when I click the "unscroll" button to push the scrollview back to where it came from, nothing happens. I have posted the entire code here. Please check where the fault lies !!. Already spent a sizeable amount of time on it.
-(IBAction)unscrollClicked:(id)sender
{
//[viewController.view removeFromSuperview];
[UIView beginAnimations:#"back to original size" context:nil];
scrollView.contentSize=viewController.view.bounds.size;
//scrollView.contentSize=viewController.view.bounds.size;
[UIView commitAnimations];
}
-(IBAction)scrollClicked:(id)sender
{
//viewController.view.backgroundColor=[UIColor orangeColor];
viewController.view.frame=CGRectMake(0, 410, 320, 460);
//[self.view addSubview:viewController.view];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,40, 320, 400)];//(0,0,320,160)
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
//[MyView setFrame:CGRectMake (0, 0, 320, 170)];
viewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
scrollView.contentSize = viewController.view.bounds.size;
scrollView.bounces = YES;
scrollView.bouncesZoom = YES;
scrollView.scrollEnabled = YES;
scrollView.minimumZoomScale = 0.5;
scrollView.maximumZoomScale = 5.0;
scrollView.delegate = self;
[scrollView addSubview: viewController.view];
[self.view addSubview:scrollView];
[self moveScrollView:scrollView];
}
-(void) moveScrollView:(UIScrollView *)scrollView
{
CGFloat scrollamount=400;
[scrollView setContentOffset:CGPointMake(0,scrollamount) animated:YES];
}
1st problem i see with this code is that you initialize scrollView in scrollClicked and never store pointer to it, so in unscrollClicked pointer should be nil.
Another problem is that as far as i know, animation is conducted this way:
[UIView beginAnimations:#"Animate" context:nil];
[UIView setAnimationDuration:2];
[UIView setAnimationBeginsFromCurrentState:YES];
[somView setFrame:CGRectMake(100, 100, 100, 100)];
[UIView commitAnimations];