Вот скелет ... тогда вы можете получить более подробную информацию в предлагаемых документах. Это очень просто, но имеет рандомизацию, и вы можете создать экземпляр со своим собственным изображением. Я создал контейнер изображений как UIViewController, и в моем основном (или ваш AppDelegate или RootViewController) вы создаете экземпляр в viewDidLoad. Методы, которые должны быть перегружены в вашем AppDelegate (код находится в конце поста), чтобы он получал сотрясения, являются:
- viewWillAppear
- viewDidAppear
- viewWillDisappear
- viewDidDisappear
- canBecomeFirstResponder
- becomeFirstResponder
- nextResponder
Вы становитесь респондентом в viewWillAppear, и вам нужно включить уведомления устройства (подтверждено, что есть задокументированная ошибка), чтобы вызывать методы движения.
- motionBegan: withEvent
- motionEnded: withEvent
Мне нравится ставить NSLog (@ "% s", FUNCTION ); утверждение во всех моих впервые написанных методах, таким образом я могу быстро определить, что чего-то не хватает, чтобы получить мои события, правильно инициализировать и т. д. Это просто мой стиль.
AnimatedImage.h isA ViewController
@interface AnimatedImage : UIViewController {
UIImageView *image;
UILabel *label;
float cx;
float cy;
float duration;
float repeat;
}
@property (nonatomic, retain) UIImageView *image;
@property (nonatomic, retain) UILabel *label;
-(id) initWithImageName: (NSString*) imageName;
-(IBAction) shake;
AnimatedImage.m
#include <stdlib.h>
#define random() (arc4random() % ((unsigned)RAND_MAX + 1))
#import "AnimatedImage.h"
@implementation AnimatedImage
@synthesize image;
@synthesize label;
-(id) initWithImageName: (NSString*) imageName {
NSLog(@"%s", __FUNCTION__);
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
return self;
}
-(IBAction) shake {
cx = 0.90 + (random() % 10) / 100; // cx = 0.95;
cy = 0.90 + (random() % 10) / 100; // cy = 0.95;
duration = ( 5.0 + random() % 10) / 1000.0;
repeat = (65.0 + random() % 20);
image.transform = CGAffineTransformScale(CGAffineTransformIdentity, cx, cy);
[UIView beginAnimations: @"identifier" context: @"shake"];
[UIView setAnimationDelegate:image.superclass];
[UIView setAnimationDuration: duration]; // 0.008];
[UIView setAnimationRepeatCount: repeat]; // 85.0];
[UIView setAnimationRepeatAutoreverses: YES];
image.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
[UIView commitAnimations];
}
-(IBAction) bounce {
image.transform = CGAffineTransformTranslate(image.transform, -20, -6);
[UIView beginAnimations: @"identifier" context: @"bounce"];
[UIView setAnimationDelegate:image.superclass];
[UIView setAnimationDuration: duration];
[UIView setAnimationRepeatCount: repeat];
[UIView setAnimationRepeatAutoreverses: YES];
image.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
[UIView commitAnimations];
}
@end
Этот «корневой или главный» делегат является UIViewController. Я оставил детали, чтобы показать его простоту, но все же оставил свой «трассировочный» код, который я считаю необходимым для первоначальной отладки. Кроме того, в качестве отступления, я считаю, что необходимо перегрузить motionBegan, даже если вам нужно только событие motionEnded. Я помню, что мое приложение не работало, а затем я добавил motionBegan, и он начал вызывать motionEnded. Это вроде «имеет смысл, что так будет, но у меня нет документации, подтверждающей это. Простой эксперимент после того, как вы его заработаете, может подтвердить или опровергнуть мой комментарий.
- (void)viewDidLoad {
[super viewDidLoad];
[super becomeFirstResponder];
.
.
.
NSLog(@"%s", __FUNCTION__);
NSLog(@"%s: I %s first responder! (%@)", __FUNCTION__, [self isFirstResponder] ? "am" : "am not", self);
.
.<created image in this ViewController's NIB using IB>
.
someImage = (UIImageView *) [self.view viewWithTag:TAG_SOMEIMAGE];
aniImage = [[AnimatedImage alloc] init];
aniImage.image = someImage;
}
-(void) viewWillAppear: (BOOL) animated{
NSLog(@"%s", __FUNCTION__);
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(receivedRotate:)
name: UIDeviceOrientationDidChangeNotification
object: nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"%s", __FUNCTION__);
[super becomeFirstResponder];
assert( [self canPerformAction:@selector(motionEnded:withEvent:) withSender:self] );
}
- (void)viewWillDisappear:(BOOL)animated {
NSLog(@"%s", __FUNCTION__);
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver: self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
NSLog(@"%s", __FUNCTION__);
[super resignFirstResponder];
}
- (BOOL)canBecomeFirstResponder {
NSLog(@"%s", __FUNCTION__);
return YES;
}
- (BOOL)becomeFirstResponder {
NSLog(@"%s", __FUNCTION__);
return YES;
}
- (UIResponder *)nextResponder {
NSLog(@"%s", __FUNCTION__);
return [self.view superview];
}
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"%s", __FUNCTION__);
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"%s", __FUNCTION__);
if( [self isFirstResponder] ) {
[aniImage shake];
}
}
Этот код работает, но если я вычеркнул слишком много деталей, просто спросите, и я обязательно добавлю достаточно, чтобы помочь вам в этом. Это было действительно полезным для меня заданием, и я с радостью делюсь им с кем-то, кто ищет помощь в этом же опыте.