📜 ⬆️ ⬇️

Creating dynamic animations in WatchKit

Found this article in the drafts. If you do not publish it now, never before - it will become irrevocably obsolete, and its place is only in the garbage.

Not so long ago, Apple introduced the WatchKit Framework for developing applications for its brand Apple Watch. At the moment, iOS 8.3 SDK is very limited - all code is executed on the iPhone / iPad, and the clock is only the interface and pictures. Thus, for any interaction with interface elements, the code is executed on the iOS device, and the signal passes from the clock to the device via Bluetooth and back. Creating animations from pre-cut frames is a rather primitive task and has already been chewed on in many blogs. Under the cat we are talking about creating dynamic animation, frames that are prepared in CoreGraphics.



To prepare animation frames, we will use one graphics context, redrawing the background on it or simply clearing the content before drawing each frame.
')
NSInteger framesCount = 8; CGRect rect = CGRectMake(0,0,100,100); NSMutableArray *images = [NSMutableArray array]; UIGraphicsBeginImageContextWithOptions(rect.size, YES, [WKInterfaceDevice currentDevice].screenScale); for (NSInteger frameIndex = 0; frameIndex < framesCount; frameIndex++) { [self.backgroundImage drawAtPoint:CGPointZero]; // or CGContextClearRect(UIGraphicsGetCurrentContext(), rect); // Draw frame #`frameIndex` of `framesCount` UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); [images addObject:image]; } UIGraphicsEndImageContext(); 

An array of frames must be converted into one picture and sent to the clock cache:

 UIImage *image = [UIImage animatedImageWithImages:images duration:0.5]; [[WKInterfaceDevice currentDevice] addCachedImage:image name:@"myAnimation"]; 

In this case, we follow Apple's recommendations :
IMPORTANT

When using the images, it is necessary to create a single image. Do not cache the images for the individual frames.

But we won’t be able to find out when the picture is uploaded to the clock, so don’t try to display the animation instantly, you need a delay of at least half a second. Otherwise, the clock will spin a circle of progress - which will ruin us all the gameplay. In order not to force the user to wait, it is better to cache the picture in advance so that it has time to cache.

 [self.image setImageNamed:@"myAnimation"]; [self.image startAnimating]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.image stopAnimating]; [self.image setImage:nil]; }); 

This method does not leave it possible to accurately select the number of animation cycles, but it works. I never managed to use the `-startAnimatingWithImagesInRange: duration: repeatCount:` method to display dynamic animations. Most frustrating is the inability to find out when the images really fall on the clock. Because of this, you have to underestimate the FPS and hope that the animations will be loaded.

Here are some numbers obtained on the simulator: a simple animation 150x150 (scale 2.0) of 8 frames weighs about 80kb, and it takes about 1-2 seconds to load. Reducing the quality of PNG images to 16bit (5 bits per component and 1 alpha) only increased the total weight of the animation to 100Kb, which is at least strange; perhaps it is worth trying a palette PNG 8bit.

Source: https://habr.com/ru/post/254397/


All Articles