مثيل Uiview متعددة لا يعمل
-
18-09-2019 - |
سؤال
لدي فئة Subclass Uiview في فئة ترتد مع التسارع. تظهر فئة ترتد هذه الصورة وتحريكها على الشاشة. عند نقل جهاز iPhone، ترتد هذه الصورة على الشاشة.
عندما أقوم بإنشاء مثيل متعدد، يعمل المثيل الأخير فقط بشكل صحيح:
// 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]];
}
هذه هي فئة الارتداد:
//
// 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
تطبيق:
//
// 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
هل بإمكانك مساعدتي؟
المحلول
ذلك بسبب self.accelerometer.delegate = self;
هو تغيير sharedAccelerometer
سيكون مندوب وفقدان الواجب الأخير فقط.
نصائح أخرى
أعتقد أن فقط الرأي الأمامي سوف تحصل على رسائل التسارع. قد ترغب في إرسال رسائل العجلات إلى ViewController الخاص بك بدلا من ذلك.
ما قد أفعله هنا. (قد لا يكون أفضل شيء طويل الأجل، ولكنه سيصلح المشكلة الفورية) هو:
سأجعل الجاذبية المتسارعة متغير ثابت مشترك بين جميع مثيلات الارتداد. هذا يجعلني sence بالنسبة لي لأنه في العالم الحقيقي (الشخص الذي نحترمه) ستكون الجاذبية المتسارعة هي نفسها لجميع البونصات. (أود أيضا إعادة تسمية ترتد إلى شيء مثل BouncingView). أود الوصول إلى هذا المتغير من خلال طرق بضع من الدرجة. أيضا، سأجعل مقياس التسارع مشتركا، وله طريقة مندوبها، وسيلة فئة. ضع هذه الأشياء في صفك ويجب أن تعمل: (كنت أختبرها ولكن جهاز التطوير الخاص بي في متجر Apple Store ثابت.) أيضا، هناك أخطاء بضع جملة في رمز المثال الذي نشرته.
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;
}