UIView qui puisse être bloquée
Bonjour !
Je bloque sur un problème d'architecture.
Je souhaiterais créer une classe mère CBDBlockableView, qui hériterait de UIView et qui disposerait de deux méthodes :
@interface CBDBlockableView : UIView
@property BOOL isBlocked ;
- (void)block ;
- (void)unblock ;
@end
Je souhaiterais ensuite sous-classer allègrement cette classe.
Je voudrais que la méthode - block empêche les sous-classes de dessiner la vue (et aussi bloque les actions delegate, mais ça c'est facile) et dessine à la place, par exemple, un panneau sens interdit.
Je ne vois pas comment faire...
Impossible à votre avis ?
Colas
PS : en écrivant, j'ai un idée, un peu crade : créer deux vues l'une sur l'autre. La première, la vraie. La deuxième, le sens interdit. Finalement, je me dis que c'est pas si crade que ça... (sauf pour la mémoire)
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En fait le fait de permettre de faire "unblock" sur ta vue signifie que même si ta vue est "bloquée", il faut quand même que ses subviews existent ou soient stockées qqpart (prenant de la place mémoire) au cas où tu demandes un "unblock" un jour.
Du coup si tu veux optimiser les choses, je pense qu'il faut prendre une autre approche :
1) Prévoir une BlockableView certes avec block et unblock
2) Mais que lorsque cette BlockableView n'est pas bloquée et doit afficher du contenu, charger ce contenu depuis un XIB (qui va te fournir toutes les subviews nécessaires pour mettre en subview de cette BlockableView
- Comme ça quand ta vue est bloquée, elle va afficher juste le sens interdit (à dessiner toi-même via le DrawRect, ou bien à afficher via une bête UIImageView en subview, au choix), sans avoir besoin de charger et garder en mémoire ses subviews pour rien, donc en économisant beaucoup de mémoire dû au chargement de ces suviews.
- Et quand tu la unblock, ça va charger les subviews via un XIB que tu auras précisé, et mettre ces vues du XIB en subview de ta BlockableView, pour ne les charger que si nécessaire
- Et si tu la block à nouveau, ça pourra supprimer toutes les subviews de ta BlockableView et ainsi re-libérer de la mémoire.
Thomas a déjà présenté un SmallTalk sur le sujet lors de la session CocoaHeads Rennes #14. Les SmallTalks ne sont pas filmés donc pas dispo en vidéo, mais on a mis à disposition le projet d'exemple démontrant comment faire pour placer une UIView dans un XIB qui va automatiquement charger son contenu depuis un autre XIB. Ce n'est pas exactement le cas d'usage que tu veux (le nom du XIB est codé en dur dans la subclass, etc) mais c'est un bon point de départ pour trouver l'inspiration je pense.
Merci de ta réponse. Oui, il faut garder les subviews.
Ton approche se limite aux vues qui sont dessinées via un xib. En tous cas ça a l'air intéressant.
Pour l'instant, je reste plus convaincu par mon idée de superposer deux vues l'une sur l'autre.
Colas
Attention dans ce cas à vérifier que tu ne risques pas par erreur de permettre d'ajouter des subviews à ta BlockingView depuis l'extéieur, qui viendraient potentiellement se rajouter par dessus ta vue sens-interdit
Oui je vais faire une interface .h qui ne donnera accès que à la @property view.
Je publie ça quand j'ai fini ;-) au cas où ça intéresse des gens.
Bon du coup, j'en ai profité pour regarder un peu CGContext, CGPath, etc.
J'ai codé le signe interdit en Core Graphics.
J'utilise une astuce dont j'ai eu l'idée pour me déplacer sur le cercle (une sorte de MoveToPointOnCircle()) (lignes *** dans le code).
Si des experts lisent ceci et trouvent qu'il y a des maladresses/erreurs, je suis preneur ;-)
Si j'ai bien compris, au lieu de dessiner le cercle en entier, tu dessines le cercle en 2 temps, d'abord un demi-cercle, puis stocke le point où tu es rendu, puis dessines l'autre-demi cercle. Ce qui te permet ensuite de tracer une ligne entre le point d'arrivée et le point mémorisé à mi-chemin. C'est ça ?
Mais dans ce cas pourquoi tu as besoin de First Part et Second Part ? Du coup j'ai dû louper un truc ^^
Oui c'est ce que je fais.
En fait c'est pas un demi cercle que je trace, c'est un arc dont la longueur est gérée par le paramètre noEntryParameterForWidth (s'il vaut 1 ---> c'est un demi-cercle, s'il est plus petit ---->c'est un arc de cercle, s'il vaut 0 ----> c'est vide).
C'est en jouant sur les paramètres que je me suis rendu compte que c'était mieux quand le paramètre vaut 1 !!
Cela permet en tout cas que les "coins" de ligne transversale ne débordent pas du cercle. Je ne sais pas si c'est le cas, mais avec les stroke "épais", on a des fois ce risque, non ?
cf. pictures
En fait, je commence par dessiner un arc de cercle "vide", de l'angle alpha à l'angle alpha. Je mémorise le point. Je trace le vrai arc de cercle et enfin je rejoins les deux points.
- tracer un demi de cercle de l'angle alpha à l'angle alpha+Ï€
- mémoriser bottomLeft = le point d'arrivée
- tracer l'autre demi-cercle de l'angle alpha+Ï€ à alpha(+2*Ï€)
- tracer une ligne du point d'arrivée (qui correspond donc au point sur le cercle à l'angle alpha) et le point bottomLeft (qui correspond donc au point sur le cercle à l'angle alpha+Ï€)
Ca serait plus simple, non ? (Et plus propre que de "tracer un arc de cercle vide" ce qui me dérange un peu)
Oui c'est clairement plus simple !
Ce qui donne
Pourquoi ne pas simplement utiliser CGPointMake(CGRectGetMidX(mainRect), CGRectGetMidY(mainRect)) ?
J'ai déjà avoué sur ce forum beaucoup aimé la syntaxe [object methodWithLongName]... :-*