Archive for the 'animation' Category

07 MarHuman Interface in practice on Debty app

We’ve released new product recently. It’s called Debty. It helps to manage debts of your friends. There is a banner at the right top. If you want a promocode please request it on the twitter.

The goal was to develop something easy to use with limited features. Developing it we’ve got some useful ideas I want to share.

Design

The very custom design was also required. After a few hours of research Jeans style was chosen. I hope you’ll like it.

Beside it’s really hard to develop and support custom designs, now I see it’s too custom. App design should be more simple and less like “cartoon”. Too much details, textures and volumes are pleasure to look first 3 times, but then they detract from the main thing – functional parts.

No matter how much your design is custom or unique or extravagant, you have to abide by the law of HIG (Human Interface Guidelines). It means your controls should be right sized and placed, e.g. buttons in the UINavigationBar, and you may still use the same navigation principals with UINavigationController or UITabBar. etc.

OK-message sucks

As less OK-messages you have, better your application is. Means you shouldn’t notify user “Your tweet is posted. Press ok to continue.” – use sound notification instead or “Profile is saved” – show some small animation in saved block instead.

So just take every OK-message from your app and ask “is it really required?” and “How could I notify user without OK-message?”. You’ll see how easily you invent some new approaches. Nobody says it’s easier, but worth that.

I think that’s a different between User Interface and Human Interface.

So please look this next short. There are some tiny animations which we are proud of.

  • “Enter an amount” and “Select a debtor” OK-messages are replaced by soft vibration of inputs
  • View and Edit views are combined in one view which transforms with animation to one state to another. Yes it’s like Contacts.app does.
  • Every date has human representation like “Today”, “Tomorrow”, “3 months delay”, “refund in 8 days”. it’s changed on the way while editing.

The best UI is absence of UI. It’s so much natural to not require time for adaptation.

23 NovMac OSX Dock like animation for iPhone

Last evening I thought about Mac OSX vs. iPhone user interfaces. They have “family” likeness in usability and design, but there is a huge chasm also caused by iPhone Touch Approach of UI. We are on a new age starting, i think, the age where information is obtained by touches.

On this romantic note I want to stop talking and keep making things. The first thing I thought was original Mac OSX dock

and resolutely decided to simulate its animation on iPhone.

[youtube http://www.youtube.com/watch?v=7CkxxV5ocA0&hl=ru_RU&fs=1&]

I’ve chosen popular browsers’ icons for the buttons, don’t be surprised about IE, I

am quite neutral about this stuff ;)

There are some code snippets. Animations of activating/deactivating buttons:

#define CONST_animation_time 0.2#define CONST_enlarge_proportion 1.3

- (IBAction) activate:(UIView*)view{  CGContextRef context
= UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil
 context:context]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
 [UIView setAnimationDuration:CONST_animation_time];
[view setCenter:UpPointOfView(view)];    

 CABasicAnimation *scalingAnimation =
(CABasicAnimation *)[view.layer animationForKey:@"scaling"];    

 if (!scalingAnimation) {  scalingAnimation = [CABasicAnimation
 animationWithKeyPath:@"transform"];  scalingAnimation.repeatCount=1;
  scalingAnimation.duration=CONST_animation_time;  scalingAnimation.autoreverses=NO;
 scalingAnimation.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
 scalingAnimation.fromValue=[NSValue valueWithCATransform3D:CATransform3DMakeScale(1
.0, 1.0, 1.0)];  scalingAnimation.toValue=[NSValue valueWithCATransform3D:CATransform
3DMakeScale(CONST_enlarge_proportion, CONST_enlarge_proportion, 1.0)]; }

 [view.layer addAnimation:scalingAnimation forKey:@"scaling"]; view.layer.transform =
 CATransform3DMakeScale(CONST_enlarge_proportion, CONST_enlarge_proportion, 1.0);
[UIView commitAnimations];}

- (IBAction) deactivate:(UIView*)view{ CGContextRef context =
 UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:CONST_animation_time];
[view setCenter:DownPointOfView(view)];   

 CABasicAnimation *scalingAnimation =
(CABasicAnimation *)[view.layer animationForKey:@"descaling"];   

 if (!scalingAnimation) {  scalingAnimation =
[CABasicAnimation animationWithKeyPath:@"transform"];
 scalingAnimation.repeatCount=1;   scalingAnimation.
duration=CONST_animation_time;  scalingAnimation.
autoreverses=NO;  scalingAnimation.timingFunction =
[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseOut];  scalingAnimation.
fromValue=[NSValue valueWithCATransform3D:
CATransform3DMakeScale(CONST_enlarge_proportion,
CONST_enlarge_proportion, 1.0)];
 scalingAnimation.toValue=[NSValue valueWithCATransform3D
:CATransform3DMakeScale(1.0, 1.0, 1.0)]; }    

 [view.layer addAnimation:scalingAnimation forKey:@"descaling"];
 view.layer.transform =
CATransform3DMakeScale(1.0, 1.0, 1.0); [UIView commitAnimations];}     

- (BOOL) isMultipleTouchEnabled {return NO;}

UIView *activeView = nil;

- (BOOL) animateView :( UIView*)view atPoint:(CGPoint)point{ BOOL isviewActive =
([view isEqual:activeView]);

 if (Distance(view.center, point) <= 30)
{  if (!isviewActive)  {   [self activate:view];
 activeView = view;   return YES;  }
} else if (isviewActive) {  [self deactivate:view];
activeView = nil;  return YES; }     

 return NO;}

Don’t forget to add “QuartzCore.framework” to the project.

Simple algorithm decides which buttons to active.

When finger is down algorithm finds the nearest button and activates it.

A button is deactivated when another button is closer or down finger is far than 50 points:

- (UIView*) nearestViewToPoint:(CGPoint)point{ UIView *candidateView =
nil; CGFloat candidateDistance = 100000;

 for (UIView *v in [self subviews]) {  CGFloat dist = Distance(v.center, point);
 if (dist < candidateDistance)  {   candidateView = v;   candidateDistance = dist;  } }    

 return candidateView;}

- (void) touchesMoved:(NSSet *) touches withEvent:(UIEvent *) event{ CGPoint pt =
[[touches anyObject] locationInView:self];        

 UIView *nearestView = [self neares
tViewToPoint:pt]; if
(![activeView isEqual:nearestView])
 {  [self deactivate:activeView];  activeView = nil;       

  if (Distance(nearestView.center, pt)
 <= 30)  {   [self activate:nearestView];
  activeView = nearestView;  } }
 else if (Distance(activeView.center, pt) > 50) {
 [self deactivate:activeView];  activeView = nil; }              

 [self setNeedsDisplay];}

-(void)touchesEnded:(NSSet*)touches  withEvent:(UIEvent*)event{ if (activeView) {
 [self deactivate:activeView];   activeView = nil; }}

- (void) touchesBegan:(NSSet *)
 touches withEvent:(UIEvent *) event{ if (!activeView)
 [self touchesMoved:touches withEvent:event]; }

Obviously it’s hard to apply to real project, but quite interesting as a training on animations for iPhone SDK.

Look sources here or git directly.

17 NovMap View rotation with accelerometer

Did you ask your self how that easy or difficult to rotate a map in response to a device position in space? It’s easy.

You need a MapKit and QuartzCore frameworks being added to your project. Then a small piece of math code which can be explained by several words: rotate MKMapView to necessary agnle.

I will copy full source code, because it’s very easy:

@interface MapViewRotationViewController : UIViewController { IBOutlet UIView *viewToRotate;}

@end

#import "MapViewRotationViewController.h"#import "QuartzCore/QuartzCore.h"

#define CONST_fps 25.#define CONST_map_shift 0.15

@implementation MapViewRotationViewController

- (void)viewDidLoad {    [super viewDidLoad];

 // accelerometer settings [[UIAccelerometer sharedAccelerometer] setDelegate:self]; [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / CONST_fps)];}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{ static CGFloat ZZ = 0.; CGFloat z = (atan2(acceleration.x, acceleration.y) + M_PI);

 if (fabsf(ZZ - z) > CONST_map_shift) {  viewToRotate.layer.transform = CATransform3DMakeRotation(ZZ=z, 0., 0., 1.); }}

@end

Can’t make a video now. Please catch several screenshots instead:
http://picasaweb.google.com/s/c/bin/slideshow.swf

Try to make a MKMapView Z-rotation as a home work ;)
Download source here or git directly full package.

13 NovUIView Jump Animation code snippet

I was need to make a jumping fruits in our Road Slot game for iPhone. Now have a minute to share an animation code snippet with you, guys.

Add QuartzCore framework to the project to use animation.

#define CONST_TIME_flying 0.8f

- (void) jumpAnimationForView:(UIView*)animatedView
toPoint:(CGPoint)point { // moving CGContextRef context =
 UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context];
 [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
 [UIView setAnimationDuration:CONST_TIME_flying];
 [animatedView setCenter:point];

 // scaling CABasicAnimation *scalingAnimation =
(CABasicAnimation *)
[animatedView.layer animationForKey:@"scaling"];
if (!scalingAnimation)
 {  scalingAnimation =
[CABasicAnimation animationWithKeyPath:@"transform"];
 scalingAnimation.duration=CONST_TIME_flying/2.0f;
 scalingAnimation.autoreverses=YES;
 scalingAnimation.timingFunction =
[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseOut];
scalingAnimation.fromValue=[NSValue valueWithCATransform3D:
CATransform3DMakeScale(1.0, 1.0, 1.0)];
 scalingAnimation.toValue=[NSValue valueWithCATransform3D:
CATransform3DMakeScale(1.4, 1.4, 1.0)]; }
 [animatedView.layer addAnimation:scalingAnimation forKey:@"scaling"];
[UIView commitAnimations];}

- (IBAction) buttonPressed :( UIButton*)button{
[self jumpAnimationForView:button toPoint:
(CGPoint){rand()%320, rand()%480}];}

The UIButton simply jumps to random point on its

UIView each time you press it. That’s how it looks: