[Réglé] "Assembler" 2 vues scrollables pour n'en faire qu'une

Ben77650Ben77650 Membre
août 2014 modifié dans API UIKit #1

Bonjour à  tous,


 


Je vous explique le contexte: j'ai une UITableView scrollable avec x éléments (x dépendant du nombre d'éléments récupérés en base de données).


 


J'ai également un tableHeaderView qui est en réalité une UIScrollView avec une hauteur variable selon le contenu de ma vue.


 


Le souci étant que les 2 scrolls sont indépendants l'un de l'autre.


 


Existe t-il un moyen pour que dès que j'arrive au bas du scroll mon header cela enchaine sur le scroll de ma tableView ?


 


Merci d'avance à  ceux qui m'aideront


Réponses

  • CéroceCéroce Membre, Modérateur
    août 2014 modifié #2

    On ne peut pas trop. UITableView héritant de UIScrollView, sa frame ne change pas, ce qui change ce sont les fragments de ses vues enfants qui apparaissent à  un instant donné. En d'autres termes UIScrollView permet de faire défiler un contenu virtuel, plus grand que la frame de la scrollview.


     


    Je te conseille de n'utiliser qu'une seule table, quitte à  utiliser plusieurs sections.


  • Sinon tu pourrais pas mettre ça dans le tableHeaderView proposer par Apple je suis pas super fan ce ce qu'il fait en général mais ça à  l'air de coller à  ton cas d'utilisation


    https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableView/tableHeaderView


  • Nasatya: J'utilise le tableHeaderView proposé par Apple



    CGRect screenBounds = [[UIScreen mainScreen] bounds];
            
            UIView* theaderView;
            if(screenBounds.size.height != 568)
            {
                theaderView = [[UIView alloc] initWithFrame:CGRectMake(0, -10, _tabView.frame.size.width, 340)];
            }
            else
            {
                theaderView = [[UIView alloc] initWithFrame:CGRectMake(0, -10, _tabView.frame.size.width,430)];
            }

            theaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
            
            [theaderView addSubview:_logo];
            [theaderView addSubview:_scroll];
            _tabView.tableHeaderView = theaderView;

    Céroce: Je n'ai pas compris l'histoire de "fragments de ses vues enfants qui apparaissent à  un instant donné". Pourrais tu m'expliquer plus en détail s'il te plait ? Et qu'entends tu par une table mais plusieurs sections stp ?


     


    Merci en tout cas à  vous deux pour vos réponses


  • CéroceCéroce Membre, Modérateur

    Céroce: Je n'ai pas compris l'histoire de "fragments de ses vues enfants qui apparaissent à  un instant donné". Pourrais tu m'expliquer plus en détail s'il te plait ?

    C'est difficile à  exprimer... Mais imagine que tu veuilles afficher une image qui mesure 3000x2000 points, tu ne pourrais voir qu'un fragment de l'image à  un instant donné. Pour une table, c'est pareil.

    Et qu'entends tu par une table mais plusieurs sections stp ?

    Une UITableView est organisée en sections, qui elles-même comportent des lignes.
  • Ok merci ça me parait plus clair.


     


    Tu me conseillerais donc de mettre mon header dans une section ?


  • Ben ton headerTableView est déjà  dans un scroll pourquoi ajouter un scroll pourquoi tu impose pas qu'il prenne la taille de ta vue comme ça ton tableView serait juste à  sa suite non? et dans ce cas la tu fais en sorte que ton theaderView fasse la taille de ton contenue et tu enlève le scroll qu'il contient. Je penses que ça devrait le faire.

  • AliGatorAliGator Membre, Modérateur
    Je confirme la solution de Nasatya est la plus logique.

    Une scrollview dans une scrollview, c'est rarement une bonne idée. La tableView est déjà  une scrollview, donc suffit de mettre directement ta grande vue en headerView de ta TableView et basta, pas besoin de l'encapsuler elle-même dans une autre ScrollView.
  • Ok merci j'ai fait comme ça.


     


    Par contre j'ai une question, comment faire pour définir une hauteur dynamique qui dépends du contenu s'il vous plait



    for(UIView *view in self.theaderView.subviews)
            {
                contentRect = CGRectUnion(contentRect, view.frame);
            }
            
    NSLog(@Coucou: %f, contentRect.size.height);

    Sauf que mon log m'affiche toujours 0.000000 ce que je ne comprends pas puisque j'ai pourtant bien du contenu dans mon theaderView (ajouté grâce à  un [theaderView addSubview: myView]).


     


    Quelqu'un saurais m'aider s'il vous plait ?


  • CéroceCéroce Membre, Modérateur
    août 2014 modifié #10
    -[UITableViewDelegate tableView:heightForHeaderInSection:]
  • Tu penses vraiment que comme cela ça ne fera plus 0 ?


     


    En tout cas merci pour la manière de faire. Je faisais à  tort comme cela:



    CGRect contentRect = CGRectZero;
            
            for(UIView *view in self.theaderView.subviews)
            {
                contentRect = CGRectUnion(contentRect, view.frame);
            }
            
            NSLog(@Coucou: %f, contentRect.size.height);

            contentRect.size.width=320;
            self.scroll.contentSize=contentRect.size;
            
            theaderView = [[UIView alloc] initWithFrame:CGRectMake(0, -10, 320, contentRect.size.height)];
            
            
            theaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  • AliGatorAliGator Membre, Modérateur
    Breakpoints, debug pas à  pas, tout ça, enfin le classique quoi.

    Genre vérifie que au moment où tu appelles ton code, self.theaderView.subviews n'est pas vide (parce que tu le fais trop tôt et qu'il a pas eu le temps de charger le header du XIB, ou je ne sais quoi).

    Enfin bref, utilise les outils de debug de Xcode quoi.
  • Effectivement self.theaderView.subviews est effectivement (null) malgré le fait qu'avant je lui assigne des subViews.


     


    Comment ça je le fais trop tôt et il a pas eu le temps de charger le header ?


  • Joanna CarterJoanna Carter Membre, Modérateur


    Effectivement self.theaderView.subviews est effectivement (null) malgré le fait qu'avant je lui assigne des subViews.


     


    Comment ça je le fais trop tôt et il a pas eu le temps de charger le header ?




     


    Tu assignes les subView dans quelle méthode? Les vues des xib et storyboards ne sont pas construites qu'après l'init ; le minimum est dans viewDidLoad ou awakeFromNib

  • Je l'assigne dans mon viewDidLoad


     


    exemple:



    _signaler = [[UIButton alloc] initWithFrame:CGRectMake(1, sum+213, 319, 70)];
                [_signaler setImage:[UIImage imageNamed:@signaler.png]forState:UIControlStateNormal];
                [_signaler addTarget:self action:@selector(signalement) forControlEvents:UIControlEventTouchUpInside];
                [_scroll addSubview:_signaler];
                [theaderView addSubview:_signaler];
            



            CGRect contentRect = CGRectZero;
            
            NSLog(@View: %@",self.theaderView.subviews);
            for(UIView *view in self.theaderView.subviews)
            {
                contentRect = CGRectUnion(contentRect, view.frame);
            }
            
            NSLog(@Coucou: %f, contentRect.size.height);

            contentRect.size.width=320;
            self.scroll.contentSize=contentRect.size;
            
            theaderView = [[UIView alloc] initWithFrame:CGRectMake(0, -10, 320, contentRect.size.height)];
            
            
            theaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  • Joanna CarterJoanna Carter Membre, Modérateur

    Est-ce que tu as implémenté - tableView:viewForHeaderInSection:  ou il faut créer le headerView ?


  • AliGatorAliGator Membre, Modérateur
    Bah tu m'étonnes que ce soit nil du coup avec un code pareil...

    tu ajoutes des subviews à  un self.theaderView (qui en plus est certainement nil à  ce moment car tu ne l'as pas encore créée), et après tu crées une toute nouvelle vue theaderView = [[UIView alloc] init...].

    Faudrait peut-être créer la vue **avant** de lui ajouter des sous-vues, sinon c'est un peu évident que tu ajoutes des subviews à  un truc qui n'est pas encore créé ça va pas aller loin...
  • @Joanna: négatif je n'ai qu'un titleForHeaderInSection et un heightForHeaderInSection


     


    @Ali: Effectivement ça marche mieux comme cela, seulement un nouveau souci: il ne m'affiche que 2 objets, et pas les autres, et pourtant dans mon NSLog il y a 6 objets. Où sont passés les 4 autres objets ?


  • AliGatorAliGator Membre, Modérateur
    Breakpoints, debug pas à  pas, tout ça, enfin le classique quoi.

    Regarde la frame de chacun, s'ils sont bien positionnés les uns en dessous des autres et pas tous à  une origine Y=0, si ton CGRectUnion marche bien en conséquence, etc.

    Enfin bref, utilise les outils de debug de Xcode quoi.
  • Ben77650Ben77650 Membre
    août 2014 modifié #20

    Okay


  • Joanna CarterJoanna Carter Membre, Modérateur
    août 2014 modifié #21

    Su tu voulais créer une vue pour le header d'une section, tu devrais la créer ou dériver de UITableViewHeaderFooterView https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewHeaderFooterView_class/Reference/Reference.html et pas UIView.


     


    Du coup, il faut ajouter les subViews au contentView du UITableViewHeaderFooterView.


     


    Puis, il faut que tu implémentes tableView:viewForHeaderInSection: qui se trouve dans le protocole UITableViewDelegate et que tu ne renvoies la vue que de cette méthode.


  • AliGatorAliGator Membre, Modérateur
    Bref, faut lire le "Table View Programming Guide" quoi, où tout est expliqué.
  • Joanna CarterJoanna Carter Membre, Modérateur


    Bref, faut lire le "Table View Programming Guide" quoi, où tout est expliqué.




     


    Mais c'est tous en anglais et ce n'est pas toujours facile de comprendre les sujets techniques dans sa langue maternelle 

Connectez-vous ou Inscrivez-vous pour répondre.