I want to perform a shrink animation on a UITableVIew. I experimented a bit and found out that the animation runs much faster when I shrink a UIImageView with an image of the current state of the tableview instead of shrinking the table view itself.
I grabbed the image in a method in my main viewcontroller prior to the animation:
UIGraphicsBeginImageContext(mainTableView.bounds.size);
[resizeContainer.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Works like a charm, at least almost. On very rare occasions I get weird graphic glitches, where the UIImage starts to overlap a toolbar that lies underneath it.
I just want to make sure that I am getting the image in the right way. I am laking the necessary understand of GraphicContexts to be sure about it.
To cut a long story short, is my code correct?
Thx
In what way did you animate the table? I haven't had problems with it animating slowly. Here is an example of what I did when I had to resize my table:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[mainTableView setFrame:CGRectMake(0,43,320,176)];
[UIView commitAnimations];
The reason I would suggest not just taking a screenshot but actually animating the table is because the animation could possibly start as the table is still scrolling. For instance the user just happened to flick the table as it started animating then you would have a jump to the new state when you fade out the "screen shot" that you took.
It went away with iOS 4.0. So I guess it was a bug.
Related
I have a UIImageView that I'm moving across the screen based on a user swiping. I accomplish this using Core Animation:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
movingView.frame = theRect;
[UIView commitAnimations];
It always starts out fine, but partway through going from its original location to the "theRect" location, it stops and the UIImageView jumps back to its starting point. It's never at the same point. Sometimes gets almost all the way through before jumping back, sometimes only barely moving then jumping back. No other code is running after this. I've tried changing the duration and it doesn't seem to matter.
If I add in:
[UIView setAnimationDidStopSelector:#selector(completeAnimation:finished:context:)];
[UIView setAnimationDelegate:self];
Then it actually delays until the Duration is complete and runs the selector, even if the image itself stops and returns to its starting point almost immediately.
Hopefully someone can give me some hints at what might be going on here.
If using autolayout, you can animate the changing of the constraint, not animating the change of the frame (because when constraints are reapplied, the original location will be restored). See Animating an image view to slide upwards for an example.
I'm trying to build my first iPhone app, a Berlin museum guide, and I'm having a little trouble figuring out how to design a specific view. I did mockups of all my views with Photoshop before, but now actually making it happen in Xcode is something else, of course :-)
So, here's what I want:
[I was gonna post an image here but since I'm new I don't have enough reputation to post images.]
Find the image here:
http://img9.uploadhouse.com/fileuploads/13445/13445099d5adea77b02fe1d76755da6b81c92634.png
I want a white box with several text parts in it. A large heading, a smaller heading and a longer text that is placed next to an image. The text that goes in there is provided by my core data model and changes depending on what exhibition the user is looking at.
First question: Is there such thing as a "white box with rounded corners object" in which I can place text, images etc. or would I have to import this as a custom image? In that case, I'd have a problem if I want the box to change it's size, as with simply scaling the image the round corners would become distorted.. I'm assuming a CSS-stye approach with a top- and bottom-image and doing the middle part with a repeat-y property or something like that won't work in objective-c, right?
Second question: Does anyone have good advice on how to approach the text expand thing in general? I want the description text to initially be just a teaser so it won't take up the whole screen. If the user wants to keep reading, on tapping the "more" button the box should expand and display the entire text.
So much for the theory.. I'm a bit clueless about how to get this done and am hoping that somebody might have some good input on that.
Thanks a lot for taking the time to help a newbie :-)
I would not use a b/g image since there are going to be problems with vertical expansion, as you noted yourself. I would rather use a regular UIView and following method to make its corners round.
#import <QuartzCore/QuartzCore.h>
view.layer.cornerRadius = 5;
As for the text expansion. I would not try to make image wrapping text as it is hard.
For automatica UITextView adjustment you can do the following.
set UITextView frame smaller.
create a button "more" that will change the frame of the UITextView and animate it
example:
#define MOVE_ANIMATION_DURATION_SECONDS 0.5
-(void)maximize:(BOOL)animated{
if(animated){
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS];
[UIView setAnimationDelegate:self];
[self setMaximizedViewState];
[UIView commitAnimations];
}else
[self setMaximizedViewState];
}
-(void)minimize:(BOOL)animated{
if(animated){
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS];
[UIView setAnimationDelegate:self];
[self setMinimizedViewState];
[UIView commitAnimations];
}else
[self setMinimizedViewState];
}
-(void)setMinimizedViewState{
isMinimized = YES;
//Adjust the UITextView's frame and other properties
}
-(void)setMaximizedViewState{
isMinimized = NO;
//Adjust the UITextView's frame and other properties
}
Is there a way to make drawRect animate FROM THE PREVIOUS SCENE to the next one?
(Amazingly) you can animate inside drawRect - try it. You can fade, translate or animate any other property.
However, it starts "from fresh", from blank. So for example if you put a fade-in animation block in drawRect, the previous scene with disappear and the new scene will fade up from white.
I want the screen to fade from the previous image (drawn in the previous cycle of drawRect) to the new image I have just drawn ... err, am drawing.
Is there a way to do that, perhaps trickily by manipulating what's going on with drawRect?
This would seem to be a very common use case - blending from one scene to the next.
Does anyone know the secret?
Of course, obviously this can be done in the core animation milieu or in many other ways, but having drawRect fade from one drawRect to the next is an obvious idea. Cheers.
Astounding update thanks to the genius of WrightCS.....
Thanks only to WrightCS, we now know that drawRect handles animations perfectly. Simply paste this code at the end of any drawRect and try it:
self.alpha = 0.0;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
self.alpha = 1.0;
[UIView commitAnimations];
it treats the entire drawRect, no matter how complex, as one enormous block and it wraps it in that animation. Yes, it even includes painted in offscreen areas, bitmap rendering or anything else. Everything gets animated. Who knew?
The problem at hand - how to make it start the animation from the previous scene rather than start from blank?
Drawrect Is invisible. It happens in the 'backbuffer' which the iOS displays on screen only when you're ready with drawRect. So you can definitely not animate while in drawrect. However, you can commit animation instrucions from just about anywhere, including drawrect. But the animation will be performed afterwards.
Animation requires timing and showing different frames to the user.
You CAN do that all by yourself (constantly forcing a redraw and doing something slightly different in drawrect each the time) but that's a lot of work, especialy if you want it done right.
Luckily iOS has many animation effects programmed for you. Either using Core Animation, or the (more simple and basic) animation in UIKit. But since it works by animating certain properties of views (eg the alpha of a whole view, or the rotation of a whole view, ...) you might need to rearrange your views and subviews to make good use of it.
E.g. Each horse limb is separate subview and you animate their transformations (no redraw needed, iOS will do the rest)
E.g. The old and new frame are two separate views and you animate the new frame (which is on top) from alpha 0 to alpha 1.
You can animate the alpha:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
myObject.alpha = 0.0;
[UIView commitAnimations];
if you are under iOS 5.0+, you can use the following:
...
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
//do your stuff here
}completion:^(BOOL finished) {
//completition stuff go here
}];
...
The best thing you can do is to use two UIView instances and animate between them.
When you are starting the animation you have to know which is the original and final state of the animation. That's difficult if it's only one view.
I am rotating a UIImageView in place periodically. My view is very basic, a view inside of a UITabBar view set. If I happen to rotate my iPad while my rotation is animating then my image becomes skewed. I have checked everything I can think of in my xib file for my image, the autoresizing is turned completely off and I am not auto-resizing subviews on the parent view.
Here is my animation code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
transform = CGAffineTransformMakeRotation(convertToRadian(myDegrees));
myImage.transform = transform;
[UIView commitAnimations];
If I take my animation out then everything works as I would expect. This rotation code appears to work fine if I do not rotate my device.
What can I do to keep the built-in rotation animation from altering my animation and skewing my images?
After many different attempts, what I ended up doing here is adding a clear view with my rotating images inside of it and setting the "auto-resize sub views" to off in interface builder. You can also do this in code as needed. I had to add the UIView placeholder because the super view containing my rotating images needed to auto-resize other view objects on rotation, but this fixed the funky skewing of my images due to animation of orientation change at the same time as animating a manual rotation in place.
Hope this helps someone.
The coordinate system gets changed. I've figured this much out too... thought I had a bug. If you save the CG ... GState, then you can revert back to the coordinate system initially used. This is in Deitel and Deitel's book. I just found it. Wanted to post it for anyone also looking.
You got a clever trick though! I might use it if this won't work.
Having failed in trying to puzzle together different sources to any form of coherent approach or concept I turn, once again to the learned people of StackOverflow. My problem is quite specific and maybe that's why I'm having trouble finding information that fits or maybe I just suck at searching. Either way, here goes.
I am building an app which has a UIScrollView populated with UIViews which in turn are populated with UITableViews. I have paging and everything set up and working properly. Basically, I am trying to mirror the functionality of Safari's (mobile) tab behaviour, or (even closer to what I'm trying to achieve) Tweetdeck's main page. I couldn't post an image but if you click on the link below you'll see what I mean.
http://www.redmondpie.com/wp-content/uploads/2009/07/TweetdeckIphone04.jpg
The reason for the UITableViews are inside UIViews is that this was the only way I could figure out to make the tableViews have a space between them, instead of being right next to each other. I tried setting the size of the tableViews and the inset of the scrollView, among many things but the tableviews always ended up filling the entire scrollView. In any case, that is a separate issue, possibly
As I click on a tableView/UIView inside the scrollView I want that tableView/UIView to scale up and fill the entire screen (minus tabBar and navigationBar), and then I should be able to scale it back down by pressing the back button on the navigationBar.
Any information or nudges in the right direction is greatly appreciated.
I am doing something similar in my app:
-(void)displayPage:(int)targetedPage {
...
[UIView beginAnimations:#"MultiViewAnimate" context:nil];
[UIView setAnimationDuration:0.3];
//animate the frame
//targetedPage is the index (table view) that should be displayed
[(UITableView *)[tableViews objectAtIndex:targetedPage] setFrame:CGRectMake(0, 0, 320, 372)];
[(UITableView *)[tableViews objectAtIndex:targetedPage] setUserInteractionEnabled:YES];
...
[UIView commitAnimations];
}
-(void)displayMultiView:(id)sender {
...
[UIView beginAnimations:#"MultiViewAnimate" context:nil];
[UIView setAnimationDuration:0.3];
//animate the frame
//targetedPage is the index (table view) that I was previously looking at full screen
[(UITableView *)[tableViews objectAtIndex:targetedPage] setFrame:CGRectMake(60, 70, 200, 232)];
[(UITableView *)[tableViews objectAtIndex:targetedPage] setUserInteractionEnabled:NO];
...
[UIView commitAnimations];
}
In this code tableViews is an array of all the UITableViews that the scrollView contains.
I am doing a little more than this because I am taking a screenshot of my view and using a UIImageView for the scaled view and then animating back out to the respective UIWebView. One advantage to that approach is that I can just attach a UITapGestureRecognizer to the UIImageView and not have to mess with turning off userInteraction on the UITableView.