Custom UIAlertView @ NSObject

yass_1988yass_1988 Membre
juin 2012 modifié dans Vos applications #1
Bonjour,



voila je vous présente un petit problème que j'ai rencontré:



Dans mon viewController, j'ai une méthode qui me permet d'initialiser une classe "RenameFeature" de type NSObject en lui passant en paramètre une instance de mon viewController et d'exécuter une méthode de cette classe.



viewController.m:
-(void) exec<br />
{<br />
	 RenameFeature *Rename=[[RenameFeature alloc] init:self];<br />
	 [Rename executeAlertRename];<br />
}




la méthode de RenameFeature que j'exécute, me permet d'afficher une AlertView que j'ai customisé.



RenameFeature.h:
[color=#b41ca4]@interface[/color][color=#000000] RenameFeature : [/color]NSObject[color=#000000]&lt;[/color]UIAlertViewDelegate[color=#000000]&gt;[/color]<br />
{<br />
	[color=#578187]UIViewController[/color] * ViewController;<br />
}<br />
<br />
<br />
- ([color=#b41ca4]id[/color]) init: ([color=#578187]UIViewController[/color] *)VC;<br />
-([color=#b41ca4]void[/color])excecuteAlertRename;<br />
<br />
[color=#b41ca4]@end
[/color]



RenameFeature.m:

[/color][color=#73492c]#import [/color]&quot;RenameFeature.h&quot;[/color]<br />
[color=#c72c25][color=#73492c]#import [/color]&quot;AlertRenamePronpt.h&quot;[/color]<br />
<br />
[color=#b41ca4]@implementation[color=#000000] RenameFeature[/color][/color]<br />
<br />
- ([color=#B41CA4]id[/color]) init: ([color=#578187]UIViewController[/color] *)VC<br />
{<br />
	[color=#b41ca4]if[/color] ( [color=#b41ca4]self[/color] = [[color=#b41ca4]super[/color] [color=#401082]init[/color]] )<br />
	{<br />
		[color=#578187]ViewController=VC;[/color]<br />
	}<br />
	[color=#b41ca4]return[/color] [color=#b41ca4]self[/color];	<br />
}<br />
<br />
-([color=#b41ca4]void[/color])excecuteAlertRename<br />
{<br />
[color=#38595d][color=#000000]	[[/color][color=#b41ca4]self[/color][color=#000000] [/color]raisePromptView[color=#000000]:[/color][color=#c72c25]@&quot;Renommer&quot;[/color][color=#000000] [/color]message[color=#000000]:[/color][color=#c72c25]@&quot;Veuillez entrer un nouveau nom : &quot;[/color][color=#000000] [/color]textfieldPositionY[color=#000000]:[/color][color=#3d01d9]75[/color][color=#000000] [/color]delegate[color=#000000]:[/color][color=#578187]ViewController[/color][color=#000000]];[/color][/color]<br />
}<br />
<br />
<br />
-([color=#b41ca4]void[/color])raisePromptView:([color=#7134aa]NSString[/color]*)title message:([color=#7134aa]NSString[/color]*)message textfieldPositionY:([color=#7134aa]CGFloat[/color])posY delegate:(UIViewController *)viewController<br />
{<br />
[color=#38595d][color=#000000]	[/color][color=#578187]AlertPronpt[/color][color=#000000] * prompt = [[[/color][color=#578187]AlertRenamePronpt[/color][color=#000000] [/color][color=#401082]alloc[/color][color=#000000]] [/color]initWithTitle[color=#000000]:title [/color]message[color=#000000]:message [/color]delegate[color=#000000]:viewController  [/color]cancelButtonTitle[color=#000000]:[/color][color=#c72c25]@&quot;ANNULER&quot;[/color][color=#000000] [/color]okButtonTitle[color=#000000]:[/color][color=#c72c25]@&quot;OK&quot;[/color][color=#000000] [/color]textfieldPosY[color=#000000]:posY];[/color][/color]<br />
	[prompt [color=#401082]show[/color]];<br />
}<br />
<br />
<br />
- ([color=#b41ca4]void[/color])alertView:([color=#578187]AlertRenamePronpt[/color] *)actionSheet clickedButtonAtIndex:([color=#7134aa]NSInteger[/color])buttonIndex<br />
{<br />
	[color=#b41ca4]if[/color](buttonIndex==[color=#3d01d9]0[/color]){<br />
		[color=#401082]NSLog[/color]([color=#c72c25]@&quot;ici&quot;[/color]);<br />
	}else{<br />
		NSLog(@&quot;là &quot;);<br />
   }<br />
}<br />
<br />
[color=#b41ca4][color=#000000]@end






AlertPrompt.h:
[color=#73492c]#import [/color]&lt;Foundation/Foundation.h&gt;<br />
<br />
[color=#b41ca4]@interface[/color] AlertPronpt : [color=#7134aa]UIAlertView[/color] {<br />
	[color=#7134aa]UITextField[/color] *textField;<br />
}<br />
<br />
[color=#b41ca4]@property[color=#000000] ([/color]nonatomic[color=#000000], [/color]retain[color=#000000]) [/color][color=#7134aa]UITextField[/color][color=#000000] *textField;[/color][/color]<br />
[color=#b41ca4]@property[/color] ([color=#b41ca4]readonly[/color]) [color=#7134aa]NSString[/color] *enteredText;<br />
- ([color=#b41ca4]id[/color])initWithTitle:([color=#7134aa]NSString[/color] *)title message:([color=#7134aa]NSString[/color] *)message delegate:([color=#b41ca4]id[/color])delegate cancelButtonTitle:([color=#7134aa]NSString[/color] *)cancelButtonTitle okButtonTitle:([color=#7134aa]NSString[/color] *)okButtonTitle textfieldPosY:([color=#7134aa]CGFloat[/color])posY;<br />
<br />
[color=#b41ca4]@end[color=#000000]
[/color][/color]



AlertPrompt.m:

[/color][color=#73492c]#import [/color]&quot;AlertRenamePronpt.h&quot;[/color]<br />
<br />
[color=#b41ca4]@implementation[/color] AlertRenamePronpt<br />
<br />
[color=#b41ca4]@synthesize[/color] textField;<br />
[color=#b41ca4]@synthesize[/color] enteredText;<br />
<br />
- ([color=#b41ca4]id[/color])initWithTitle:([color=#7134aa]NSString[/color] *)title message:([color=#7134aa]NSString[/color] *)message delegate:([color=#b41ca4]id[/color])delegate cancelButtonTitle:([color=#7134aa]NSString[/color] *)cancelButtonTitle okButtonTitle:([color=#7134aa]NSString[/color] *)okayButtonTitle textfieldPosY:([color=#7134aa]CGFloat[/color])posY {<br />
<br />
	[color=#b41ca4]if[/color] ([color=#b41ca4]self[/color] = [[color=#b41ca4]super[/color] [color=#401082]initWithTitle[/color]:title [color=#401082]message[/color]:[[color=#7134aa]NSString[/color] [color=#401082]stringWithFormat[/color]:[color=#c72c25]@&quot;%@\n\n\n&quot;[/color], message] [color=#401082]delegate[/color]:delegate [color=#401082]cancelButtonTitle[/color]:cancelButtonTitle [color=#401082]otherButtonTitles[/color]:okayButtonTitle, [color=#b41ca4]nil[/color]]) {<br />
		[color=#7134aa]UITextField[/color] *theTextField = [[[color=#7134aa]UITextField[/color] [color=#401082]alloc[/color]] [color=#401082]initWithFrame[/color]:[color=#401082]CGRectMake[/color]([color=#3d01d9]20.0[/color], posY, [color=#3d01d9]245.0[/color], [color=#3d01d9]25.0[/color])];<br />
		[theTextField [color=#401082]setBackgroundColor[/color]:[[color=#7134aa]UIColor[/color] [color=#401082]whiteColor[/color]]];<br />
		[[color=#b41ca4]self[/color] [color=#401082]addSubview[/color]:theTextField];<br />
		[color=#b41ca4]self[/color].[color=#578187]textField[/color] = theTextField;<br />
[color=#401082][color=#000000]		[/color][color=#7134aa]CGAffineTransform[/color][color=#000000] translate = [/color]CGAffineTransformMakeTranslation[color=#000000]([/color][color=#3d01d9]0.0[/color][color=#000000], -[/color][color=#3d01d9]20.0[/color][color=#000000]);[/color][/color]<br />
		[[color=#b41ca4]self[/color] [color=#401082]setTransform[/color]:translate];<br />
	}<br />
[color=#b41ca4][color=#000000]	[/color]return[color=#000000] [/color]self[color=#000000];[/color][/color]<br />
}<br />
<br />
- ([color=#b41ca4]void[/color])show {<br />
	[[color=#b41ca4]super[/color] [color=#401082]show[/color]];<br />
[color=#401082][color=#000000]	[[/color][color=#578187]textField[/color][color=#000000] [/color]becomeFirstResponder[color=#000000]];[/color][/color]<br />
}<br />
<br />
- ([color=#7134aa]NSString[/color] *)enteredText {<br />
[color=#578187][color=#000000]	[/color][color=#b41ca4]return[/color][color=#000000] [/color]textField[color=#000000].[/color][color=#7134aa]text[/color][color=#000000];[/color][/color]<br />
}<br />
<br />
[color=#b41ca4]@end[/color][color=#000000]




Le soucis est que ma fenêtre d'alerte customisé s'affiche bien, par contre elle ne réagit pas quand j'appuis sur l'un des deux boutons (rien ne s'affiche). Par contre quand je met ma méthode: - (void)alertView:(AlertRenamePronpt *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

dans mon viewController là  elle fonctionne.

Du coup auriez-vous une idée, pour qu'elle fonctionne en gardant la méthode dans le "FeatureRename"?



J'ai l'impression que cette méthode ne fonctionne que dans le viewController qui supporte l'AlertView

Réponses

  • Es-tu au courant que depuis iOS 5 les UIAlertView peuvent avoir un style différent ?
    <br />
    <br />
    typedef enum {<br />
        UIAlertViewStyleDefault = 0,<br />
        UIAlertViewStyleSecureTextInput,<br />
        UIAlertViewStylePlainTextInput,<br />
        UIAlertViewStyleLoginAndPasswordInput<br />
    } UIAlertViewStyle;<br />
    




    En occurrence, ça serait UIAlertViewStylePlainTextInput qui t'intéresserait.



    Très honnêtement si il s'agit d'un projet perso que tu réalise, je te conseille de faire du iOS 5 minimum dès maintenant.
  • D'accord, donc du coup, j'ai essayé avec UIAlertViewStyleSecureTextInput:
    -([color=#b41ca4]void[/color])excecuteAlertRename<br />
    {<br />
    [color=#000000]    [/color][color=#7134AA]UIAlertView[/color][color=#000000] * test=[[[/color][color=#7134AA]UIAlertView[/color][color=#000000] [/color][color="#401082"]alloc[/color][color=#000000]] [/color][color="#401082"]initWithTitle[/color][color=#000000]:[/color][color=#C72C25]@&quot;text&quot;[/color][color=#000000] [/color][color="#401082"]message[/color][color=#000000]:[/color][color=#C72C25]@&quot;entrer&quot;[/color][color=#000000] [/color][color="#401082"]delegate[/color][color=#000000]:[/color][color="#b41ca4"]viewController[/color][color=#000000] [/color][color="#401082"]cancelButtonTitle[/color][color=#000000]:[/color][color=#C72C25]@&quot;cancel&quot;[/color][color=#000000] [/color][color="#401082"]otherButtonTitles[/color][color=#000000]:[/color][color=#C72C25]@&quot;RENOMMER&quot;[/color][color=#000000], [/color][color=#B41CA4]nil[/color][color=#000000]];[/color][color=#401082]<br />
    [color=#000000]    [test [/color]setAlertViewStyle[color=#000000]:[/color]UIAlertViewStylePlainTextInput[color=#000000]];[/color][/color]<br />
        [test [color=#401082]show[/color]];<br />
    }
    




    Pour le style c'est parfais, sauf que j'ai toujours ce même problème pour capter l'évènement de l'utilisateur quand il clique sur l'un des deux boutons avec la méthode:
    - ([color=#b41ca4]void[/color])alertView:([color=#7134aa]UIAlertView[/color] *)actionSheet clickedButtonAtIndex:([color=#7134aa]NSInteger[/color])buttonIndex
    
    qui se trouve dans ma classe "RenameFeature".
  • AliGatorAliGator Membre, Modérateur
    Bah pourtant tu as cité toi-même le code qui pose problème.

    Tu sais ce qu'est un delegate, non ?

    Tu as réfléchi pourquoi la méthode de delegate était appelée sur le viewController ? Tu as réfléchi à  ce que tu passais au paramètre "delegate" de ta méthode d'initialisation de UIAlertView ? image/wink.png' class='bbc_emoticon' alt=';)' />
  • Ce n'est pas l'instance de mon viewController que je dois passer au paramètre "delegate" de ma méthode d'inistialisation de mon UIAlertView mais l'objet courant, je remplace du coup par self.

    Mais j'ai toujours le même problème:
    -([color=#b41ca4]void[/color])excecuteAlertRename<br />
    {[color=#401082]<br />
    [color=#000000]    [/color][color=#7134aa]UIAlertView[/color][color=#000000] * test=[[[/color][color=#7134aa]UIAlertView[/color][color=#000000] [/color]alloc[color=#000000]] [/color]initWithTitle[color=#000000]:[/color][color=#c72c25]@&quot;text&quot;[/color][color=#000000] [/color]message[color=#000000]:[/color][color=#c72c25]@&quot;entrer&quot;[/color][color=#000000] [/color]delegate[color=#000000]:[/color][color=#b41ca4]self[/color][color=#000000] [/color]cancelButtonTitle[color=#000000]:[/color][color=#c72c25]@&quot;cancel&quot;[/color][color=#000000] [/color]otherButtonTitles[color=#000000]:[/color][color=#c72c25]@&quot;RENOMMER&quot;[/color][color=#000000], [/color][color=#b41ca4]nil[/color][color=#000000]];[/color][/color][color=#401082]<br />
    [color=#000000]    [test [/color]setAlertViewStyle[color=#000000]:[/color]UIAlertViewStylePlainTextInput[color=#000000]];[/color][/color]<br />
        [test [color=#401082]show[/color]];<br />
    }<br />
    <br />
    - ([color=#b41ca4]void[/color])alertView:([color=#7134aa]UIAlertView[/color] *)actionSheet clickedButtonAtIndex:([color=#7134aa]NSInteger[/color])buttonIndex<br />
    {[color=#c72c25]<br />
    [color=#000000]    i[/color][color=#B41CA4][color=#000088]f[/color][/color][color=#666600]([/color][color=#000000]buttonIndex[/color][color=#666600]==[/color][color=#3D01D9][color=#006666]0[/color][/color][color=#666600]){[/color][/color]<br />
    [color=#000000]                [/color][color=#401082][color=#660066]NSLog[/color][/color][color=#666600]([/color][color=#C72C25][color=#666600]@[/color][color=#008800]&quot;ici&quot;[/color][/color][color=#666600]);[/color]<br />
    [color=#000000]        [/color][color=#666600]}[/color][color=#000088]else[/color][color=#666600]{[/color]<br />
    [color=#000000]                [/color][color=#660066]NSLog[/color][color=#666600](@[/color][color=#008800]&quot;là &quot;[/color][color=#666600]);[/color]<br />
    [color=#000000]   [/color][color=#666600]}[/color]<br />
    }
    
  • Voila ce qui s'affiche, quand je tente d'appuyer sur l'un des deux boutons:
    [__NSMallocBlock__ alertView:clickedButtonAtIndex:]: unrecognized selector sent to instance 0x2d39d0<br />
    *** Terminating app due to uncaught exception &#39;NSInvalidArgumentException&#39;, reason: &#39;-[__NSMallocBlock__ alertView:clickedButtonAtIndex:]: unrecognized selector sent to instance 0x2d39d0&#39;
    
  • AliGatorAliGator Membre, Modérateur
    Tu as donc un problème de gestion mémoire, puisque le "self" que tu passes en paramètre de "delegate", qui est sensé être ton objet RenameFeature, quand l'alertView essaye d'appeler la méthode de delegate dessus, cela ne pointe plus sur un objet RenameFeature (mais, dans le cas de l'erreur que tu as citée, sur un NSMallocBlock).



    Concrètement, ton objet a donc été désalloué de la mémoire entre temps.
  • yass_1988yass_1988 Membre
    juin 2012 modifié #8
    Et comment faire pour contourner le problème, sachant que j'utilise ARC dans mon projet ?

    En gros comment éviter que mon objet ne soit désalloué ?
  • Aucune idée ?
  • iDevKenoiDevKeno Membre
    juin 2012 modifié #10
    As-tu encore besoin d'utiliser une sous-classe ?!



    Sinon, essaye cela :



    Dans ViewController, déclare une propriété RenameFeature
    <br />
    @property (nonatomic, retain) RenameFeature *renameFeature;<br />
    


    Ensuite, tu la synthétise
    <br />
    @synthesize renameFeature;<br />
    


    Pour finir ...
    <br />
    renameFeature = [[RenameFeature alloc] init:self];<br />
    [renameFeature excecuteAlertRename];<br />
    




    ça devrait fonctionner.



    iDevKeno
  • Non, je suis obligé de mètre en place ma méthode -(void)alertView:clickedButtonAtIndex dans ma classe "RenameFeature" et je dois créer et appeler UIAlertView depuis "RenameFeature", si j'avais pas eu ces contraintes là , j'aurais déjà  résolu la question.
  • AliGatorAliGator Membre, Modérateur
    Bah si. La solution de iDevKeno devrait résoudre ton problème, en s'assurant de retenir ton objet RenameFeature plutôt que le laisser disparaitre.
  • yep, niquel!

    Merci pour le coup de main.
Connectez-vous ou Inscrivez-vous pour répondre.