I have implemented Circular transitions as i asked in
animating UIView transitions like expand dot to circle
using following code:
-(IBAction)nextViewOpen
{
NextViewVC *NextView= [self.storyboard instantiateViewControllerWithIdentifier:#"RBANextViewVC"];
[NextView.view.layer setCornerRadius:25.0f];
[NextView.view.layer setMasksToBounds:YES];
NextView.view.frame=CGRectMake(100,120, 1, 1);
[self.view addSubview:NextView.view];
[self setRoundedView:NextView.view toDiameter:5];
[UIView animateWithDuration:5.0 animations:^{
====== [self setRoundedView:NextView.view toDiameter:480]; ======
}
completion:^(BOOL finished)
{
NextView.view.frame=CGRectMake(0, 0, 320, 480);
NextView.view.layer.cornerRadius = 0;
}
];
}
-(void)setRoundedView:(UIView *)roundedView toDiameter:(float)newSize;
{
CGPoint saveCenter =roundedView.center;
CGRect newFrame = CGRectMake(roundedView.frame.origin.x, roundedView.frame.origin.y, newSize, newSize);
roundedView.frame = newFrame;
//roundedView.layer.cornerRadius = newSize / 2.0;
roundedView.layer.cornerRadius = roundedView.frame.size.width / 2.0;
roundedView.center = saveCenter;
roundedView.clipsToBounds = YES;
}
But it is having some issues
the view gets complete circle shape at the end of the animated transition, initially its not having rounded corners perfectly
Related
I have to create custom MKMapView annotations, which look almost the same as the ones iOS provides, but have different color (white) and slightly different shape.
My first attempt was to prevent opening the original black UIAnnotationViews and in AnnotationView's setSelected:animated: added a new subview to the same UIAnnotationView. I have animated this view after adding it to the superview. This had only one problem: my custom button in the annotation was not clickable.
After this I've found this excellent example:
https://github.com/tochi/custom-callout-sample-for-iOS
This adds a new CalloutAnnotation to the map when the user clicks on a PinAnnotation. PinAnnotations have no AnnotationViews, only CalloutAnnotations do.
This works fine, except that I can't figure out how to do the iOS-like initial zooming animation on the annotation views when they are created.
The animation I want to use is the following (found here on SO and worked fine with my first attempt):
- (void)animateCalloutAppearance:(CalloutAnnotationView *)annotaitonView
{
self.endFrame = annotaitonView.frame;
CGFloat scale = 0.001f;
annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
[UIView animateWithDuration:0.075f delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
CGFloat scale = 1.2f;
annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGFloat scale = 0.90;
annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.075 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGFloat scale = 1.0;
annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
} completion:nil];
}];
}];
}
#pragma mark - The helper methods
- (CGFloat)relativeParentXPosition:(CalloutAnnotationView *)annotationView {
return annotationView.bounds.size.width / 2.0f;
}
- (CGFloat)xTransformForScale:(CGFloat)scale andAnnotation:(CalloutAnnotationView *)annotationView {
CGFloat xDistanceFromCenterToParent = self.endFrame.size.width / 2.0f - [self relativeParentXPosition:annotationView];
CGFloat transformX = (xDistanceFromCenterToParent * scale) - xDistanceFromCenterToParent;
return transformX;
}
- (CGFloat)yTransformForScale:(CGFloat)scale {
CGFloat yDistanceFromCenterToParent = self.endFrame.size.height / 2.0f;
CGFloat transformY = yDistanceFromCenterToParent - yDistanceFromCenterToParent * scale;
return transformY;
}
I've found the answer on this blog: http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-1/
The tricky part is that you have to do the animation in the CalloutAnnotationView's didMoveToSuperView :)
- (void)didMoveToSuperview
{
[self animateCalloutAppearance:self];
}
I hope it helps somebody else :)
I am trying to figure out how to set my tabbaritem icon(image) to 0 so I can give it a fade animation once it loads onto the screen... but I just don't know how to do it..
this is how I am adding the images to the tabbar..
- (void)viewDidAppear:(BOOL)animated
{
self.button0.image = [UIImage imageNamed:#"icon1.png"];
self.button1.image = [UIImage imageNamed:#"icon2.png"];
self.button2.image = [UIImage imageNamed:#"icon3.png"];
self.button3.image = [UIImage imageNamed:#"icon4.png"];
self.button4.image = [UIImage imageNamed:#"icon5.png"];
self.button5.image = [UIImage imageNamed:#"icon1.png"];
}
I will animate them with a method that looks something like this
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
// Do your animations here
}
completion:^(BOOL finished){
if (finished) {
// Do your method here after your animation.
}
}];
any help would be greatly appreciated.
Update this is my latest attempt thats not working yet..
buttonImage0.image = [UIImage imageNamed:#"icon1.png"];
buttonImage0.alpha = 0.0;
self.button0.image = buttonImage0.image;
[UIView animateWithDuration:0.1f
delay:0.0f
options:UIViewAnimationOptionTransitionNone
animations:^{
// Do your animations here.
buttonImage0.alpha = 1.0;
}
completion:^(BOOL finished){
if (finished) {
// Do your method here after your animation.
}
}];
UIButton is a subclass of UIView. UIView has an alpha property.
Try:
self.button0.alpha = 0.0;
self.button1.alpha = 0.0;
self.button2.alpha = 0.0;
self.button3.alpha = 0.0;
self.button4.alpha = 0.0;
self.button5.alpha = 0.0;
in your viewDidAppear;
Then put your easing function in the animateWithDuration routine using the same alpha property!
I'm fooling around with Apple's ScrollViewSuite, TapToZoom app, trying to place a view on the zoomed image. Here's what I want to do: on double tap, rotate the image by pi/2, zoom it by a factor of 8, then place a subview in the scrollView on top of the transformed image.
I know the view's desired frame in the original coordinate system. So I need to transform those coordinates to the new system after the zoom...
From the ScrollViewSuite...
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
// double tap zooms in
float newScale = [imageScrollView zoomScale] * 8; // my custom zoom
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[imageScrollView zoomToRect:zoomRect animated:YES];
[self rotateView:imageScrollView by:M_PI_2]; // then the twist
}
My rotation code...
- (void)rotateView:(UIView *)anImageView by:(CGFloat)spin {
[UIView animateWithDuration:0.5 delay: 0.0
options: UIViewAnimationOptionAllowUserInteraction
animations:^{
anImageView.transform = CGAffineTransformMakeRotation(spin);
}
completion:^(BOOL finished){}];
}
Then, after the zoom is finished, place a view at a known location in the original coordinate system. This is where I think I need some help...
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)_scale {
CGFloat coX = scrollView.contentOffset.x;
CGFloat coY = scrollView.contentOffset.y;
// try to build the forward transformation that got us here, then invert it
CGAffineTransform rotate = CGAffineTransformMakeRotation(M_PI_2);
CGAffineTransform scale = CGAffineTransformMakeScale(_scale, _scale);
// should these be negative? some confusion here.
CGAffineTransform translate = CGAffineTransformMakeTranslation(coX, coY);
// what's the right order of concatenation on these? more confusion
CGAffineTransform aft0 = CGAffineTransformConcat(rotate, scale);
CGAffineTransform aft1 = CGAffineTransformConcat(aft0, translate);
// invert it
CGAffineTransform aft = CGAffineTransformInvert(aft1);
// this is the fixed rect in original coordinate system of the image
// the image is at 0,0 320, 300 in the view, so this will only work
// when the image is at the origin... need to fix that later,too.
CGRect rect = CGRectMake(248, 40, 90, 160);
CGRect xformRect = CGRectApplyAffineTransform(rect, aft);
// build a subview with this rect
UIView *newView = [scrollView viewWithTag:888];
if (!newView) {
newView = [[UIView alloc] initWithFrame:xformRect];
newView.backgroundColor = [UIColor yellowColor];
newView.tag = 888;
[scrollView addSubview:newView];
} else {
newView.frame = xformRect;
}
// see where it landed...
NSLog(#"%f,%f %f,%f", xformRect.origin.x, xformRect.origin.y, xformRect.size.width, xformRect.size.height);
}
I have 2 questions on uiscrollview.
First question:
I have imageviews on uiscrollview(at bottom of screen) and let users to drag the image view out of uiscroll view.
I place fingers on top of the imageView to drag it out but uiscrollview takes the touch and scrolls.
I guess I need to let the imageView gets the touch event first (if the touch event occurred on imageView)
If finger direction is almost horizontal, give the touch event to scrollview so that it can scroll, otherwise(finger direction is not horizontal) let the user drag the imageView.
(I have scrollView.directionalLockEnabled = YES)
I wonder how this can be done?
Second Question:
User can send the imageView back to uiScrollView by double tapping the imageView.
When I do that, the scrollview is not scrollable until I drag out any imageViews in the scrollView.
Don't know what's causing this problem..
Below is my code to send the imageView back to uiscrollview.
aDragView.userInteractionEnabled = NO;
CGPoint contentOffset = self.puzzlePieceScrollView.contentOffset;
float x = contentOffset.x;
int addIndex = x / widthWithPadding;
aDragView.scrollContainerIndex = addIndex;
CGRect newFrame;
int puzzlePieceCount = 0;
[UIView beginAnimations:#"addDragView" context: [aDragView retain]];
for(UIView* subview in [self.puzzlePieceScrollView subviews])
{
if([subview isKindOfClass: [DragView class]])
{
DragView* dragView = (DragView*)subview;
if(dragView.scrollContainerIndex >= addIndex)
{
dragView.scrollContainerIndex += 1;
newFrame = dragView.frame;
newFrame.origin.x += widthWithPadding;
dragView.frame = newFrame;
}
++puzzlePieceCount;
}
}
newFrame = aDragView.frame;
newFrame.origin.x = [self getOriginXForScrollIndex: addIndex];
newFrame.origin.y = self.frame.origin.y + upperPadding;
aDragView.frame = newFrame;
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
[UIView commitAnimations];
float newWidth = std::max((puzzlePieceCount+1) * widthWithPadding, [[UIScreen mainScreen] bounds].size.width );
CGSize newContentSize = self.puzzlePieceScrollView.contentSize;
newContentSize.width = newWidth;
self.puzzlePieceScrollView.contentSize = newContentSize;
- (void) animationFinished:(NSString*)animationId finished:(BOOL)finished context:(void*)context
{
if ([animationId isEqualToString:#"addDragView"])
{
DragView* aDragView = (DragView*)context;
// add to puzzlePieceScrollView
CGPoint p;
p = CGPointMake(aDragView.bounds.size.width * 0.5, aDragView.bounds.size.height * 0.5);
CGPoint newCenter = [aDragView convertPoint: p toView: self.puzzlePieceScrollView];
aDragView.center = newCenter;
[self.puzzlePieceScrollView addSubview: aDragView];
aDragView.userInteractionEnabled = YES;
[aDragView release];
}
self.puzzlePieceScrollView.userInteractionEnabled = YES;
}
I have added some table and other vies in a scrollview. scrolling in tables are working fine. But in the parent scrollview, when scrolling, a vacillating vertical scrollbars are shown, sometimes it even come to the middle of the screen. sometime show at the left side of the screen. and not limited to the vertical scrollbar region. When I set the showsVerticalScrollIndicator = NO, it is not shown. But do you know why the scrollbar is moving around.
DashboardView is a subclass of UIScrollView.
dashboard=[[DashboardView alloc] initWithFrame:fullScreenRect];
dashboard.contentSize = CGSizeMake(320,700); // must do!
dashboard.showsVerticalScrollIndicator = YES;
dashboard.bounces = YES;
self.view = dashboard;
#implementation DashboardView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (void) layoutSubviews{
NSArray *views = self.subviews;
[UIView beginAnimations:#"CollapseExpand" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
UIView *view = [views objectAtIndex: 0];
CGRect rect = view.frame;
for (int i = 1; i < [views count]; i++ ) {
view = [views objectAtIndex:i];
view.frame = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height, view.frame.size.width, view.frame.size.height);
rect = view.frame;
}
[UIView commitAnimations];
}
Remember that scrollbars is subviews of scroll too. Exclude it from views array, before doing something with views.
Yap. that solved my problem. It seems Scrollbars are a kind of UIImageView. If anybody need it, this is my new code which works fine.
(void) layoutSubviews{
NSArray *views = self.subviews;
[UIView beginAnimations:#"CollapseExpand" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
//CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
// [self.view insertSubview:balanceView belowSubview:profileView];
UIView *view = [views objectAtIndex: 0];
CGRect rect = view.frame;
for (int i = 1; i < [views count]; i++ ) {
view = [views objectAtIndex:i];
if ([view isMemberOfClass: [UIView class] ]) {
//CFShow(view);
view.frame = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height, view.frame.size.width, view.frame.size.height);
rect = view.frame;
}
}
[UIView commitAnimations];
}