[Résolu] Autolayout+UIScrollView+UIImageView zoomable centrée...

LeChatNoirLeChatNoir Membre, Modérateur
décembre 2014 modifié dans Objective-C, Swift, C, C++ #1

Hello,


 


Qu'on soit bien clair : autolayout et sizeclass are my friends now :)


C'est juste le pied.


 


Mais par contre, ça peut être assez compliqué parfois et le cas dont je parle l'est car on parle de ScrollView...


 


Le besoin : en mode paysage, j'ai une UIScrollView et à  l'intérieur, une UIImageView.


J'adapte la largeur de l'UIImageView en fonction de la hauteur de la scrollView.


 


Les contraintes :


 


=> scrollview :


 


lead, trail, top et bottom à  0 pour que la scrollView soit full screen.


 


=> UIImageView : c'est là  que ça se gâte


 


top et bottom à  0 car je veux voir tte mon image.


lead et trail à  0 avec une prio faible car sinon, la contentView de la scrollView ne se met pas à  jour


Center horizontally car je veux que l'image soit au centre.


 


Tout fonctionne bien. Quand la largeur de mon image est plus grande que l'écran, ca scrolle et le zoom marche bien.


 


Par contre, quand la largeur de mon image est inférieure à  celle de l'écran, l'image est bien centrée MAIS quand je zoom, elle ne se recentre pas.... Elle garde son centrage avec le zoom initial donc se décale vers la droite au zoom...


 


 


Y a t il une solution simple à  ce pb ?


Réponses

  • LeChatNoirLeChatNoir Membre, Modérateur

    La réponse est oui :)


     


    Il suffit de sous-classer la scrollView et d'implémenter le centrage. Magique !



    @interface centeringScrollView : UIScrollView
    @end

    @implementation centeringScrollView

    -(void)layoutSubviews
    {
    [super layoutSubviews];
    UIView* v = [self.delegate viewForZoomingInScrollView:self];
    CGFloat svw = self.bounds.size.width;
    CGFloat svh = self.bounds.size.height;
    CGFloat vw = v.frame.size.width;
    CGFloat vh = v.frame.size.height;
    CGRect f = v.frame;
    if (vw < svw)
    f.origin.x = (svw - vw) / 2.0;
    else
    f.origin.x = 0;
    if (vh < svh)
    f.origin.y = (svh - vh) / 2.0;
    else
    f.origin.y = 0;
    v.frame = f;
    }

    @end

  • LeChatNoirLeChatNoir Membre, Modérateur
    janvier 2015 modifié #3

    Petite tweak pour iOS7 qui n'appelle pas layoutSubviews quand on rotationne... (grrrrr)


    Dans la méthode 



    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration


    Un petit bout de code de ce genre fait l'affaire... Ca va pas plaire au croco....



    self.sv.zoomScale+=0.1;
    self.sv.zoomScale-=0.1;

    Pas taper  :o


  • AliGatorAliGator Membre, Modérateur
    J'ai été raisonnable pendant les fêtes et donc j'ai pas vomi au retour du réveillon, mais là , je sens que ça va pas tarder...
  • muqaddarmuqaddar Administrateur


    Petite tweak pour iOS7 qui n'appelle pas layoutSubviews quand on rotationne... (grrrrr)


    Dans la méthode 



    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration


    Un petit bout de code de ce genre fait l'affaire... Ca va pas plaire au croco....



    self.sv.zoomScale+=0.1;
    self.sv.zoomScale-=0.1;

    Pas taper  :o




     


    Pourquoi tu n'appelles pas le code qui fait tes calculs dans une méthode perso de ta sous-classe quand tu fais la rotation ?


    Et tu appelles aussi la méthode depuis layoutSubviews.

  • LeChatNoirLeChatNoir Membre, Modérateur

    pas idiot...


    :*   :o  


  • LeChatNoirLeChatNoir Membre, Modérateur

    Ok, c'est mieux. J'ai fait une nouvelle méthode dans ma scrollView et je l'appelle depuis le layoutSubviews de cette scrollView et pour iOS7, je dois également l'appeler depuis le willAnimateRotationToInterfaceOrientation.


     


    C'est plus propre merci.


     


    Seulement le problème, c'est que le layoutSubviews est appelé plein de fois quand la scrollView scroll... Alors qu'a priori, je m'en fiche... Moi ce qui m'intéresse, c'est quand la scrollView change de taille (init et rotation). Pas quand ca scrolle...


     


    Ca gène en rien en fait mais j'ai un peu peur que les perfs soient pas au RDV sur un iPhone 4s (sur mon 6, pas de pb).


     


    D'où la question : dans une sous-classe d'UIScrollView, y a t il moyen de détecter que la scrollView est en train de scroller ?


  • muqaddarmuqaddar Administrateur


    D'où la question : dans une sous-classe d'UIScrollView, y a t il moyen de détecter que la scrollView est en train de scroller ?




     


    Oui, va voir les delegates de UIScrollView.


    Mais ça changera pas ton problème.

  • LeChatNoirLeChatNoir Membre, Modérateur

    oui j'avais pensé gérer un booléen avec les delegates qui vont bien mais c'est vraiment dans ma sous-classe que ça m'intéresse...


    Alors je pourrai reporter ce booléen dans ma sous-classe mais bon... Ca me parait credo une fois de plus ^^


  • AliGatorAliGator Membre, Modérateur
    Bah sinon tu mémorises la taille de ta scrollView dans une property et à  chaque appel de layoutSubviews tu appelles "super" mais ensuite tu ne fais ton code que si la taille est différente,


    Ou alors tu surcharges setBounds.
Connectez-vous ou Inscrivez-vous pour répondre.