Hériter de UIView mais ne pas avoir de Frame rectangulaire

GreensourceGreensource Membre
03:59 modifié dans API UIKit #1
Bonjour bonjour!
Je vais avoir besoin d'implémenter une vue un peu particulière. habituellement les vues contiennent une frame (ainsi qu'un bound, je ne vois pas bien la différence d'ailleurs) qui sont rectangulaire (CGRect).
Or moi je voudrais utiliser tout ce que propose UIView mais avec une frame hexagonale.
Du coup dans ma réflexion je suis partie pour faire hériter mon objet de UIView mais en transformant un paquets de fonction.
Du genre faire une méthode:
-(void)drawHexagon

Et cette méthode serait appelé par drawRect.

Pour être franc ça me parait un peu bricolage, mais je n'ai trouver uqe ça pour l'instant. Z'en penser quoi?

Réponses

  • AliGatorAliGator Membre, Modérateur
    03:59 modifié #2
    Tu trouveras peut-être des éléments de réponse ici.

    A mon avis pour ce que tu veux faire, surcharger [tt]pointInside:withEvent:[/tt] pour filtrer les événments (TouchEvents), et utiliser un clipPath (voir CGContextClip) pour le dessiner (dans drawRect, créer le clipPath, appeller drawHexagon, puis relâcher le clipPath) est suffisant pour tes besoins.
  • GreensourceGreensource Membre
    03:59 modifié #3
    Merci,
    à  propos de ton premier lien, ce que je veux correspondrais à  un mix entre "display" et "control".

    Sinon je pense que ça peut me sauver ce que tu proposes. Pour le clipPath nickel c'est exactement ce qu'il me faut au niveau du dessin. Et pour les events, si j'ai bien compris, en cas de chevauchement la case dira: "non non moi je répond pas c'est en dehors!" et grâce à  la méthode hitTest:withEvent: on finira bien par trouvé la bonne case qui doit répondre.

    Donc en gros ce que je vais devoir faire:
    -Une UIView (ex:Board) qui contient toutes les vues cases (UIVIew) au dessus de la pile des events
    -Lors d'un events, une méthode de Board qui appel hitTest:withEvent: pour que la bonne case réponde.

    Je vais essayer de bricoler ça, tu penses que ça dois fonctionner ainsi?
  • AliGatorAliGator Membre, Modérateur
    03:59 modifié #4
    hitTest est appelé tout seul par la boucle d'events qd tu fais un touch il me emble. Et cette méthode appelle toute seul pointInside:withEvent: sur chacune des views de la hierarchy pour savoir laquelle doit répondre et à  qui envoyer l'event. Enfin c'est ce que j'ai cru capter en parcourant la doc que je t'ai donnée.
    Donc c'est pointInside: que tu dois surcharger je pense, pour tester si le touch est dans l'hexagone que doit représenter ta view.
  • AliGatorAliGator Membre, Modérateur
    mai 2009 modifié #5
    Voir la receipe/chapitre "Clipped Views" (p51) du "iPhone Developer's CookBook" d'Erica Sadun, elle explique tout comment faire ça dedans.

    Et ça confirme ce que je pensais c'est bien comme ça qu'elle fait : [tt]CGContextClip[/tt] pour faire le clipping au niveau du dessin, et réimplémentation de [tt]pointInside:withEvent:[/tt] pour le "hitTest" (pour dire quand un "touch" sur ta vue doit "être intercepté" ou "passer au travers").
  • GreensourceGreensource Membre
    03:59 modifié #6
    Trop bien! En effet je viens de regarder son bouquin! Ca m'arrange trop, ça va rendre mon code beaucoup plus jolie et adapté à  Cocoa!

    Merci!
  • GreensourceGreensource Membre
    juin 2009 modifié #7
    Bonjour! Alors j'ai parcouru le forum, les références d'Apple et je crois avoir bien compris le principe du Clipping des vues, très pratique!
    Pourtant j'ai un souci, je voulais, dans un vue (UIView) ajouter des UIImageView (une seule pour le moment) mais clippé, je veux qu'elles aient une forme hexagonale. J'ai donc créer un path dans l'UIImageView, ajouter au contexte courant au moment de dessiner et pour finir Clipper le contexte.
    Pourtant, l'UIImage reste désespérément carré, de la taille de l'image!

    Je vous fournit le code du mini projet pour vous faire voir.
    (le path n'est pas encore un hexagone, j'ai un peu de mal à  retranscrire les coordonnées des points)
    Ma seule piste serait que je n'aurais pas le bon contexte, mais je ne sais pas comment obtenir le bon. Je sais qu'ils sont empiler mais pas comment dépiler ^^

    Merci

    [edit] Mon projet n'est peut-être pas super clair: le controller GWBoardController ajoute une UIImageView(GWCaseView) à  la vue générale (GWBoardView) D'ailleurs je ne sais pas si c'est comme ça que l'ont dois faire?
  • Philippe49Philippe49 Membre
    juin 2009 modifié #8
    Si tu mets une UIImageView en subview de ton UIView, le dessin se fait ainsi :
    1) Dessin de l'UIView, clippé , donc l'hexagone ...
    2) Par dessus, se dessine l'image view.
    Tu as donc une image view au-dessus d'un hexagone.

    Si tu veux que l'hexagone de l'uiVIew clippe l'image, il faut dessiner celle-ci dans la méthode drawRect  de l'UIView avec une des méthodes ad-hoc de UIImage comme drawAtPoint: ,

  • GreensourceGreensource Membre
    03:59 modifié #9
    Heu attend j'ai l'impression qu'on s'est mal compris.
    J'ai une grande vue qui rempli tout l'écran:
    UIView * GWBoardView
    

    Cette vue a comme subviews des:
    UIImageView * hexagonView
    


    Donc forcément j'initialise les hexagonView avec initWithImage et celà  à  pour effet de dessiner l'image (qui est un rectangle).
    C'est seulement ensuite que la méthode drawRect: de hexagonView est appelé, n'est ce pas?
    Et moi c'est bien dans cette méthode que je récupère le contexte courant et que je le clip (Avec un path en forme d'hexagone).

    Moi j'ai vraiment l'impression de faire:
    1- Dessin de l'image de l'UIImageView (initWithImage:)
    2- Clipping (drawRect:)
  • GreensourceGreensource Membre
    03:59 modifié #10
    Raaaa je vais devenir dingue!!! Je comprends plus rien à  cette histoire de context!
    Le context récupérer avec UIGraphicsGetCurrentContext() c'est bien ce lui de la vue dans laquelle on l'appelle?
    Par exemple je l'appelle dans une UIImageView, dans la fonction drawRect:.
    Dans ce context je dessine un hexagone qui se situe à  peu près en zéro pour se mettre pile dans l'UIImageView. L'UIImageView quand à  elle se situe au beau mileu de ma vue Mère (Celle qui rempli tout l'écran).
    Or l'hexagone se peint à  l'origine de l'écran pas de ma UIImageView!!!
    Un screen pour expliquer:
Connectez-vous ou Inscrivez-vous pour répondre.