recyclage de sous-classe UIview

sublimema

Membre confirmé
21 Septembre 2010
17
2
37
Toulouse
www.whoprod.fr
bonjour a tous!

je vous contact car j'ai un problème pour "recyclé" des UIView, j'aimerais faire comme le système qui gère les cellule d'une tableView...

j'ai créé une sous-class de UIView "ImageView" que je crée a chaque événement touchesMoved et auquel j'associe les valeurs de départ(centre, imageView et angle) ;

Bloc de code:
if([arrayImageMorte count]<0]){
      imageView * newImage=[[BallView alloc] init];
      newImage.centre=centre;
      newImage.angle=joystickDroit.angle;
      newImage.delegate=self;
      [newImage creationImage];
      [self.view addSubview:newImage];
}

et si mon arrayImageMorte contient quelque chose:

Bloc de code:
else {
	ImageView * recyclImage=[arrayImageMorte objectAtIndex:0];
	recyclImage.centre=centre;
	recyclImage.angle=joystickDroit.angle;
	recyclImage.anglePrecis=joystickDroit.anglePrecis;
	recyclImage.delegate=self;
	[recyclImage recyclerBall];
	[ballMorteArray removeObjectAtIndex:0];
}

cette classe déclare les instances suivante: centre (center de UIImageView), imageView (UIImageView), et angle(float).

et j'aimerais les recyclé des qu'elle sorte de la vue...

j'ai donc créée une méthode délégué dans mon ImageView
Bloc de code:
[self.delegate ajouterBall:self];
;

qui ajouterais mon imageView dans un tableau des quelle sort du view.frame...

Bloc de code:
-(void)ajouterImageMorte:(ImageView*)image{
	printf("message");
		
	if(CGRectContainsPoint(self.view.frame, image.center)==NO){
		[imageMorteArray addObject:balle];
		[NSObject cancelPreviousPerformRequestsWithTarget:self];
	}
	[self performSelector:@selector(ajouterImage) withObject:image afterDelay:timerInterval];
}

et c'est la que sa dérape... j'ai écrite le code "en gros" car j'ai essayé plusieur solution mais c'est a peur prés sa qu'il devrait se passé mais pas en ces "terme"

la console me sort une erreur [ImageViewController ajouterImage]: unrecognized selector sent to instance avant de pouvoir avoir le message "message"...

je ne vois plus d'ou sa peut venir, en vérité j'ai l'impression que sa vient de plein de truc... bref je suis perdu!
 
Bloc de code:
if([arrayImageMorte count]<0])

Ce code ne sera jamais exécuté. T'as déjà vu une liste qui contient -12 éléments ?

j'ai donc créée une méthode délégué dans mon ImageView

A priori, ce n'est pas à l'imageview de dire quand elle sort de la frame de la vue contenante, mais c'est à la vue contenante de savoir qu'elle est sortie et de la placer dans les vues "recyclées". C'est ainsi que fonctionne une UITableView.
Si tu attrapes le -touchesMoved: dans la BallView (ce que j'ai l'impression que tu fais), le mouvement sera limité à la frame de la BallView. C'est dans la vue contenante que l'événement doit être géré.

la console me sort une erreur [ImageViewController ajouterImage]: unrecognized selector sent to instance avant de pouvoir avoir le message "message"...

Ajoute une catégorie sur NSObject qui contient cette méthode -[ajouterImage:]. En plaçant un point d'arrêt sur cette méthode, tu verras bien qui l'appelle.

bref je suis perdu!
Moi aussi, tes explications ne sont pas claires du tout !
Je pense que si tu arrives à poser le problème clairement, tu le régleras en même temps.
 
yep

Ce code ne sera jamais exécuté. T'as déjà vu une liste qui contient -12 éléments ?

comme je l'ai dit (avec des fautes, certe ^^)

j'ai écrite le code "en gros"

j'ai écrit le code en "gros" mais à la base j'ai du écrire
Bloc de code:
if(![arrayImageMorte count]>=0])
ou alors
Bloc de code:
if(arrayImageMorte != nul])
ou encore
Bloc de code:
if([arrayImageMorte objectAtIndex:1]!= nul])
le probleme n'est pas la...

mais c'est à la vue contenante de savoir qu'elle est sortie et de la placer dans les vues "recyclées".

je suis entierement d'accord mais en fait je pense que je me suis mal fait comprendre en essayant de ne pas surchargé la page de code... faisons court:

ViewController.h:
Bloc de code:
#import <UIKit/UIKit.h>
#import "Joystick.h"
#import "ImageView.h"
@class ImageView;
@class Joystick;

@interface ViewController : UIViewController <ImageViewDelegate>{
	NSMutableArray *imageMorteArray;
	Joystick *joystickDroit;
	Joystick *joystickGauche;
	
}
@property (nonatomic,retain) NSMutableArray * ballMorteArray;

-(void)imageController;
-(IBAction)ajouterImage:(ImageView *)Image;

@end

ViewController.m:
Bloc de code:
#import "ViewController.h"
#import "ImageView.h"
#import "Joystick.h"

@implementation ViewController
@synthesize imageMorteArray;

- (void)viewDidLoad {
    [super viewDidLoad];
	CGPoint centre;
	centre.x=240;
	centre.y=150;
	sol.center=centre;
	
	CGRect joystickGaucheRect = CGRectMake(360, 180, 100, 100);
	CGRect joystickDroitRect= CGRectMake(20, 180, 100, 100); 
	joystickGauche = [[Joystick alloc] initWithFrame:joystickGaucheRect]; 
	joystickDroit = [[Joystick alloc] initWithFrame:joystickDroitRect];
	
	imageMorteArray=[[NSMutableArray alloc] init];
	
	[self.view addSubview:joystickDroit];
	[self.view addSubview:joystickGauche];
	
	[joystickDroit release];
	[joystickGauche release];
	
	[self tirController];
	
}

-(void)imageController{
	if(joystickDroit.isSelected==YES) {
		CGPoint centre;
		centre.x=10*sin((joystickDroit.anglePrecis)*deg2rar)+avion.center.x;
		centre.y=10*cos((joystickDroit.anglePrecis)*deg2rar)+(avion.center.y-15);
		
		if ([ballMorteArray count]>0) {
			ImageView * recyclImage=[ImageMorteArray objectAtIndex:0];
			recyclImage.centre=centre;
			recyclImage.angle=joystickDroit.angle;
			recyclImage.delegate=self;
			[recyclImage recycleImage];
			[ballMorteArray removeObjectAtIndex:0];
		}else{
			ImageView * newImage=[[ImageView alloc] init];
			newImage.centre=centre;
			newImage.angle=joystickDroit.angle;
			newImage.delegate=self;
			[newImage creationImage];
			[self.view addSubview:newImage];

		}
	}
	
	[self performSelector:@selector(imageController) withObject:nil afterDelay:timerInterval];
}



-(void)ajouterImage:(ImageView *)image{
		
		if(CGRectContainsPoint(self.view.frame,image.centre){
			[ballMorteArray addObject:balle];
			[NSObject cancelPreviousPerformRequestsWithTarget:self];
		}
	
	
	[self performSelector:@selector(ajouterImage) withObject:image afterDelay:timerInterval];
	
	
}


- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
	[super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	self.imageMorteArray=nil;
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
	[self viewDidLoad];
	[super dealloc];
}

@end

ImageView.h
Bloc de code:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@protocol ImageViewDelegate;

@interface ImageView : UIView {
	id <ImageViewDelegate> delegate;
	UIImageView *imageView;
	int angle;
	CGPoint centre;
}

@property(nonatomic,assign) id<ImageViewDelegate> delegate;
@property(nonatomic,assign) UIImageView *imageView;
@property(nonatomic,assign) int angle;
@property(nonatomic,assign) CGPoint centre;

-(void)creationImage;
-(void)recycleImage;
-(void)trajectoireImage;

@end

@protocol ImageViewDelegate
-(IBAction)ajouterImage:(ImageView*)Image;
@end

ImageView.m
Bloc de code:
#import "BallView.h"


const float timeInterval=1./30.;
const float deg2rad = M_PI/180;

@implementation ImageView

@synthesize imageView, angle, centre, delegate;


-(void)creationImage{
	self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"image%i.png",self.angle]]];

	self.imageView.frame=CGRectMake(self.centre.x-8, self.centre.y-8, 16, 16);
	[self.delegate ajouterImage:self];
	[self addSubview:imageView];
	[self trajectoireImage];
}

-(void)recycleImage{
	self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"image%i.png",self.angle]]
	[self.delegate ajouterImage:self];
	[self trajectoireImage];
	
}

-(void)trajectoireImage{
	centre.x+=15*sin(self.angle*deg2rad);
	centre.y+=15*cos(self.angle*deg2rad);
	self.imageView.center=centre;
	[self performSelector:@selector(trajectoireImage) withObject:nil afterDelay:timeInterval];}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (void)dealloc {;
	self.imageView=nil;
    [super dealloc];
}


@end

la sa devrai être bien écrit sans prendre trop de place...
 
:rolleyes: l'expression left sera toujours executé avant quand je lis ton code sans offence: t'es un JIJO.
Bloc de code:
if(myarray && [arrayImageMorte count])
{

}
else if(myarray && ![arrayImageMorte count])
{

}
else
{

}
mais bon j'ecrirais

if (myarray == nil)
{
    assert(0);
}
if([arrayImageMorte count])
{

}
else
{

}

BABA

les collections d'objet ne peuvent pas avoir d'element NIL ou NULL 
mais peuvent avoir une representation "objet NULL"

[NSNull null];

padawan de longues heures de travaille t'attende, car tu as de grosses 
lacunes sur certain point tres facile a comprendre concernant la programmation objet.
tu devrais prendre une feuille de papier et de plus utiliser des clips comme les CALayers et les animations
parce que ca ete ecrit par de gens qui pensent et qui non pas de probleme avec des maths de 4eme... choses dont tu sembles etre depourvu(e) :rateau::p:D:p et ecoute ce que te dis Céroce (et lis entre les lignes on peut sentir une bonne dose d'humour et de cynisme de la part de notre ami Céroce chose que tu sembles manquer) au lieu d'argumenter avec des inepties et de t'enfoncer dans ton chmeurk-C :rolleyes::p:)

NOTE POUR LES NEWBIES:
1- vous nous faites marrer
2- vous etes tres mauvais a part quelques rares exceptions, accepter le
3- ecouter les grands ils zensaventrbeaucoupplusquilsne disent meme quand ils trollent.
4- faites ce que les grands vous disent ou arretez tout de suite if not you would commit suicide in a couple of years realizing you were such a jerk and dumb and such a low human being
 
je sais que je suis pas bon du tout... mais bon comme on dit, mieux vaut posé une question et passé pour un con une fois que ne rien demandé et le resté toute sa vie...

bref je suis largué quoi... et même si vos explication vous paraissent claire moi je suis un peu long a la detente sur ce genre de truc..
 
Je trouve que ton code est plutôt bien écrit, mais il y a un problème conceptuel:
Cocoa n'est pas faite pour les jeux. De part ses origines, le moteur graphique, Quartz (alias Core Graphics) est plutôt adapté au graphisme vectoriel et la PAO.

Il y a de la magie dans Cocoa: on crée une UIImageView, on l'ajoute à une vue parente. Pour l'animer, il suffit de changer les propriétés. Dans les coulisses, ce qui se passe c'est que la vue est dessinée dans une CALayer qui est une abstraction pour une CGLayer qui elle-même est une abstraction pour un polygone OpenGL auquel est appliqué une texture. Quand on change la propriété frame d'une CALayer, un thread est créé qui va calculer les dimensions de la CALayer dans le temps et la déplacer/redimensionner.
Core Animation est très chouette, elle permet d'ajouter quelques animations dans une appli tout en restant relativement concentré sur notre travail. Cependant, Core Animation est faite pour animer des objets de l'IHM.

Utiliser Core Animation ou Core Graphics pour un jeu est non seulement compliqué, mais surtout, provoque de gros problèmes de performances. C'est pourquoi les jeux utilisent directement OpenGL.
Jette un &#339;il à Cocos2D.

Tu peux tout à fait continuer à utiliser Cocoa pour les menus et la gestion des joysticks.


Pour finir: à quoi sert de recycler les vues ? Créer une UITableViewCell est long: il faut créer et configurer tous les contrôles qui la composent. Créer un "sprite" n'est pas long; inutile de chercher à les recycler.