instancia UIView múltiple no funciona
-
18-09-2019 - |
Pregunta
Tengo clase UIView subclase de una clase de rebote con el acelerómetro. Esta clase de rebote mostrar una imagen y se mueven en la pantalla. Cuando el dispositivo iPhone se mueve, esta imagen de rebote en la pantalla.
Cuando creo instancia múltiple, solamente última instancia properlty trabajo:
// in the MainViewController.m
Bounce *heart[100];
for(int i = 0; i < 10; i++) {
rx = (arc4random() % 300) + 10;
ry = (arc4random() % 300) + 10;
NSLog(@"random %d %d", rx, ry);
heart[i] = [[Bounce alloc] initWithPNG:@"Heart.png"
position:CGPointMake(rx, ry) size:CGSizeMake(64, 64)];
heart[i].velocity = CGPointMake(1.0, 1.0);
[self.view addSubview: heart[i]];
}
Esta es la clase de rebote:
//
// Bounce.h
// iMakeLove
//
// Created by Giovambattista Fazioli on 06/11/09.
// Copyright 2009 Saidmade srl. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface Bounce : UIView <UIAccelerometerDelegate> {
CGPoint position;
CGSize size;
CGPoint velocity;
NSTimer *objTimer;
NSString *pngName;
CGFloat bounce;
CGFloat gravity;
CGPoint acceleratedGravity;
CGPoint lastTouch;
CGPoint currentTouch;
BOOL dragging;
UIAccelerometer *accelerometer;
}
@property CGPoint position;
@property CGSize size;
@property CGPoint velocity;
@property(nonatomic,retain)NSString *pngName;
@property(nonatomic,retain)NSTimer *objTimer;
@property CGFloat bounce;
@property CGFloat gravity;
@property CGPoint acceleratedGravity;
@property CGPoint lastTouch;
@property CGPoint currentTouch;
@property BOOL dragging;
- (id)initWithPNG:(NSString*)imageName position:(CGPoint)p size:(CGSize)s;
- (void)update;
- (void)onTimer;
- (void)startPrevent;
@end
Implementación:
//
// Bounce.m
// iMakeLove
//
// Created by Giovambattista Fazioli on 06/11/09.
// Copyright 2009 Saidmade srl. All rights reserved.
//
#import "Bounce.h"
@implementation Bounce
@synthesize position, size;
@synthesize objTimer;
@synthesize velocity;
@synthesize pngName;
@synthesize bounce;
@synthesize gravity, acceleratedGravity;
@synthesize lastTouch, currentTouch;
@synthesize dragging;
- (id)initWithPNG:(NSString*)imageName position:(CGPoint)p size:(CGSize)s {
if (self = [super initWithFrame:CGRectMake(p.x, p.y, s.width, s.height)]) {
[self setPngName:imageName];
[self setPosition:p];
[self setSize:s];
[self setBackgroundColor:[UIColor clearColor]];
// Set default gravity and bounce
[self setBounce:-0.9f];
[self setGravity:0.5f];
[self setAcceleratedGravity:CGPointMake(0.0, gravity)];
[self setDragging:NO];
UIImageView *prezzie = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, s.width, s.height)];
prezzie.image = [UIImage imageNamed:imageName];
[self addSubview:prezzie];
[prezzie release];
self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.delegate = self;
}
return self;
}
- (void)startPrevent {
if (objTimer == nil) {
objTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
}
}
- (void)update {
[self setNeedsDisplay];
if(dragging) return;
velocity.x += acceleratedGravity.x;
velocity.y += acceleratedGravity.y;
position.x += velocity.x;
position.y += velocity.y;
if(position.x + size.width >= 320.0) {
position.x = 320.0 - size.width;
velocity.x *= bounce;
} else if(position.x <= 0.0) {
velocity.x *= bounce;
}
if(position.y + size.height >= 480.0) {
position.y = 480.0 - size.height;
velocity.y *= bounce;
} else if(position.y <= 0.0) {
velocity.y *= bounce;
}
self.frame = CGRectMake(position.x, position.y, size.width, size.height);
}
- (void)onTimer {
[self update];
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
/* EVENTS */
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
acceleratedGravity.x = acceleration.x * gravity;
acceleratedGravity.y = -acceleration.y * gravity;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// First, lets check to make sure the timer has been initiated
if (objTimer == nil) {
objTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
}
UITouch *touch = [touches anyObject];
[self setCurrentTouch:[touch locationInView:self]];
CGFloat dx = currentTouch.x - position.x;
CGFloat dy = currentTouch.y - position.y;
CGFloat dist = sqrt(dx * dx + dy * dy);
if(dist < size.width) {
[self setVelocity:CGPointMake(0.0, 0.0)];
[self setDragging:YES];
}
[self setLastTouch:currentTouch];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
[self setCurrentTouch:[touch locationInView:self]];
[self setDragging:YES];
[self setVelocity:CGPointMake(currentTouch.x - lastTouch.x, currentTouch.y - lastTouch.y)];
[self setLastTouch:currentTouch];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self setDragging:NO];
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void)dealloc {
[super dealloc];
}
@end
¿Me puede ayudar?
Solución
Esto se debe a self.accelerometer.delegate = self;
es cambiar el delegado del sharedAccelerometer
y sólo la última asignación tendrá efecto.
Otros consejos
Creo que sólo la más frontal vista obtendrá los mensajes del acelerómetro. Es posible que desee los mensajes acelerómetro para ser enviados a su viewcontroller lugar.
Lo que podría hacer aquí. (Puede que no sea lo mejor a largo plazo, pero se solucionará el problema inmediato) es la siguiente:
Me gustaría hacer la gravedad acelerado una variable estática compartida entre todas las instancias de rebote. Esto hace que el SENCE para mí, porque en el mundo real (el que estamos simulando) Accelerated gravedad sería la misma para todos los rebotes. (También me cambio el nombre de rebote a algo así como BouncingView). Me acceder a esa variable a través de un par de métodos de clase. Además, me gustaría hacer el acelerómetro compartida, y tienen su método delegado, un método de clase. Poner esto en su clase y que debería funcionar:. (. Que había prueba, pero mi máquina de desarrollo se encuentra en la tienda de Apple consiguiendo fija) Además, hay un par de errores de sintaxis en el código de ejemplo informados
static CGCGPoint acceleratedGravity;
static UIAccelerometer *accelerometer;
-(void) init {
/* Everything Else */
self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.delegate = self;
/*Everything Else */
}
+(CGPoint) acceleratedGravity {
return acceleratedGravity;
}
+(void) setAcceleratedGravity:(CGPoint) _acceleratedGravity {
acceleratedGravity = _acceleratedGravity;
}
+ (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
acceleratedGravity.x = acceleration.x * gravity;
acceleratedGravity.y = -acceleration.y * gravity;
}