Problem animating size change in a custom-drawn view - iphone

I have a custom UIView that implements drawRect to render itself with a gradient background and a 1-pixel black border around the edge, and some text.
In my parent view controller, I am attempting to animate my custom view from its original small size to full-screen, using this code:
[UIView beginAnimations:nil context:NULL];
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect detailRect = CGRectOffset(screenRect, 0, -screenRect.origin.y);
[dayDetail.view setFrame:detailRect];
[UIView commitAnimations];
This works, but drawRect in my custom view is only called once when the view is initially created. As a result the resizing just takes the original small image and blows it up to full screen, so the border of the full-size view is now many pixels wide instead of one, and the text gets expanded in size as well.
Is there any way to set this up so that drawRect is called continuously as the view is being animated from small to full-screen? Basically, I want my custom rendering code to handle the appearance of the view no matter what size it is at any point in time.

I've had the exact same problem and this is how I solved it:
dayDetail.view.contentStretch = CGRectMake(0.5, 0.5, 0.0, 0.0);
That will stretch the middle pixel only. Read the documentation to learn how to modify that behavior. You could certainly ask me, but reading the documentation is probably quicker. Besides, I would probably just quote the documentation.

Related

Animate UIView grow/shrink

I have a UILabel I want to animate growing and shrinking. While the size changes I need the bottom left corner to remain static so that it always appears directly above a bottom toolbar. I am using the following code to make the label grow:
[UIView animateWithDuration:kAnimationDuration delay:0.0 options:UIViewAnimationCurveEaseInOut
animations:^{
CGFloat lblHeight = 42.0f;
[label setFrame:CGRectMake(0.0,
CGRectGetMaxY(self.view.bounds) - kBottomBarHeight - lblHeight,
CGRectGetMaxX(self.view.bounds),
lblHeight)];
} completion:^(BOOL finished) { }];
and to make it shrink I use the same logic except that lblHeight is set to 17.0f
The view correctly grows but when I try to shrink it the frame change animation is not animated. It blips into the new size and then animates into the new origin/location. I need the frame change to be animated. Can anyone see what I'm doing wrong?
After some tinkering I've managed to get the desired behavior by doing the following.
In the expand method, I use the UIView animation to alter the frame.
In the shrink method, I use the UIView animation to alter the bounds and center.
I'm a little baffled as to why this works but trying to shrink with the frame does not. If anyone can share some insight into this that would be great.
You should not really use frames to animate, rather you should use the transform property of your label.
However, since you want one corner to remain static, I think its best you use Core Animation. CALayer has a property called anchorPoint that determines which point a layer will rotate with respect to, and I'm pretty sure it is also valid for grow/shrink effects.

clipping a UIView while zooming in

I have a custom UIView that draws some data and another more detailed view that draws some components of the first view. What I want to do is after a gesture, zoom in, hide the first view, and then show the second view to give the user the context that they are zooming in deeper.
I thought I would start by doing something like this:
CGAffineTransform zoomTransform = CGAffineTransformMakeScale(2, 2);
[UIView animateWithDuration:2 animations:^{
self.chromoMap.transform = zoomTransform;
}];
It does zoom in on that area by scaling that UIView. However, I don't want my UIView to actually grow. If my CGRect is {0, 0}, {100, 100}. I want the frame of the UIView to stay the same, but just the contents inside it to scale by 2 to give that zoom effect. How would I do that? Thanks.
It seems I can just add another transparent UIView on top of it with clip subviews enabled to get that effect.

Scrolling a patterned background on UIView

I have a simple UIView which I'm filling with a patterned background, like this
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"backgroundPattern"]];
I want to be able to manipulate the origin of the view by modifying its bounds property and have the background move with the change in origin (as if the background is fixed to the content, not floating behind it). Is this possible? Currently the background seems fixed to the view's frame instead of its bounds and the pattern doesn't scroll when the content scrolls.
To change the origin I'm using a block animation like this
self.bounds = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
[UIView animateWithDuration:1. delay:0. options:UIViewAnimationOptionRepeat animations:^{
self.bounds = CGRectMake(0, 100, self.bounds.size.width, self.bounds.size.height);
} completion:nil];
With that code, my child views repeatedly scroll and reset, but the background stays fixed in place. Is it possible to specify a background which scrolls with the view instead?
I haven't been able to find anything on making a background pattern "stick" to the view's origin system. My solution for my app has been to make a child view and set the background pattern on that. Then the child view will move with the origin change and the background pattern will follow it. The problem with that solution is that the child view has to be large enough to cover the range of potential origins, which can be difficult to handle if the content area might be arbitrarily large.
You could generate an instance of your view again in the direction the user pans and add it to an NSMutableArray to be accessed and moved based on the offset of the world.

Changing UIWebView frame without changing content size

I'm trying to animate a UIWebview being removed from the screen. I'm using an animation block to set the frame height to 0. That works fine, the problem is the content size of the web view immediately takes the new frame height. So the content disappears and the background animates off. How can I stop that from happening? Here's my animation block.
// Change frame height.
[UIView animateWithDuration:1.0f
animations:^ {
// Animate the frame to the full height
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, 0);
}
];
Thanks
So if you want the content to remain where it is, you'll probably have to 'cheat' this.
Apple do this themselves on many transitions - if you go into slow animation mode on the iOS simulator, or on Mac OS you can see how it works. Unfortunately a UIWebView is very limited in scope for customisation...the only property that controls scaling is the scalesToFit value.
A different approach would be to capture the UIWebView as an image, replace the webview with that image (to the user this is seamless), and then perform the animation on the image itself. Since you're just changing the frame of a straight forward image you then won't run into any of these problems (you can also change the animation effect: if you image scales to fit the frame the content will be 'squeezed', or you can just have it cropped).

UIView loses background when animated up

I am working on an iOS app and am having trouble with a really tall UIView (2400px tall). The UIView contains a really long form that's been broken down into 5 parts. As the user completes one part of the form, I would like to slide the UIView up to reveal the next part. I present the UIView modally.
The problem that I am having is that when I slide up the UIView, the background slides up along with the objects in the first section and the next section is left with a clear background. The code I use to slide the UIView is:
- (IBAction)slideUp {
// Slide the view up the screen to reveal the next section
CGRect frame = self.view.frame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.75];
frame.origin.y = -480;
self.view.frame = frame;
[UIView commitAnimations];
}
All of the objects in the really tall UIView slide up fine, I'm just losing my background color. Any idea why?
Thanks!
Is your background being rendered by some sort of "background view" that's sized to fit the screen?
In any case, you should probably use a UIScrollView with scrolling disabled instead of a really long UIView. You can then simply animate the contentOffset property to scroll the controls up, but the scrollview itself can simply be screen-sized.
Instead of using self.view.frame, i would highly recommend you create an IBOutlet for the really long view so that the code looks like self.longView.frame.
This will help making it clear which views you are working with.
Right now i am betting that you are animating the wrong view.