Ajouter un zoom sur un UIScrollView

stounfrstounfr Membre
08:00 modifié dans API UIKit #1
Bonjour,

Petit nouveau dans le developpement iPhone, je souhaiterai avoir vos lumière :
J'ai un UIScrollView qui m'affiche une image et qui fonctionne pour le défilement...
Je voudrais rajouter à  ce UIScrollView un zoom in et zoom out.
Est ce possible et si oui vers ou chercher car ce que j'ai trouvé sur la doc apple ne fonctionne pas (ou je dois pas bien faire les choses)...

Merci de votre aide.
Stounfr

Réponses

  • CéroceCéroce Membre, Modérateur
    08:00 modifié #2
    Oui c'est possible, en gros, il existe deux principes différents:

    1) Modifier les matrices de transformation
    Je développerai davantage s'il y a besoin, mais en gros, ça modifie les coordonnées avant le dessin.


    2) Dessiner plus gros
    Si tu as un rectangle de dimensions 100x100 et que tu le dessines à  200x200, tu as effectivement fait un zoom à  200%.

    Dans ton cas, j'imagine que tu utilises une UIImageView. Tu règles son imageScaling à  NSScaleProportionally ou NSScaleToFit (ainsi, l'image prendra toute la taille de la vue).
    Quand une image est placée dans l'UIImageView, tu regardes les dimensions de l'image, et tu changes la taille de l'UIImageView (frameSize) pour qu'elle corresponde à  la taille de l'image, multipliée par le facteur de zoom.

    Si tu n'as pas compris, n'hésite pas à  demander, je te pondrai du code.
  • stounfrstounfr Membre
    08:00 modifié #3
    Merci pour ta réponse,

    voici mon code pour ma classe MyViewController

    MyViewController.h :
    <br />#import &lt;UIKit/UIKit.h&gt;<br /><br />@class MyScrollView;<br /><br />@interface MyViewController : UIViewController<br />{<br />	IBOutlet UIScrollView *scrollView1;<br />	IBOutlet UIScrollView *scrollView2;<br />}<br /><br />@property (nonatomic, retain) UIView *scrollView1;<br />@property (nonatomic, retain) UIView *scrollView2;<br /><br />@end<br />
    


    Et voici MyViewController.m
    <br />#import &quot;MyViewController.h&quot;<br /><br />@implementation MyViewController<br /><br />@synthesize scrollView1, scrollView2;<br /><br /><br /><br /><br />- (void)viewDidLoad<br />{<br />	self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];<br /><br />	[scrollView1 setBackgroundColor:[UIColor blackColor]];<br />	[scrollView1 setCanCancelContentTouches:NO];<br />	scrollView1.clipsToBounds = YES;	// default is NO, we want to restrict drawing within our scrollview<br />	scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;<br />	UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@&quot;GUAD.tif&quot;]];<br />	[scrollView1 addSubview:imageView];<br />	[scrollView1 setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];<br />	[scrollView1 setScrollEnabled:YES];<br />	[imageView release];<br /><br />}<br /><br />- (void)dealloc<br />{	<br />	[scrollView1 release];<br />	[scrollView2 release];<br />	<br />	[super dealloc];<br />}<br /><br />- (void)didReceiveMemoryWarning<br />{<br />	// invoke super&#39;s implementation to do the Right Thing, but also release the input controller since we can do that	<br />	// In practice this is unlikely to be used in this application, and it would be of little benefit,<br />	// but the principle is the important thing.<br />	//<br />	[super didReceiveMemoryWarning];<br />}<br /><br />@end<br />
    


    dans mon interface bluilder ma view contient un UIScrollView qui affiche mon images.
    Ma UIScrollView fait 280X360 et affiche bien mon image de 2000X2000. Le défilement marche au poil.
    J'avais lu sur le forum ceci dans le sujet http://www.objective-cocoa.org/forum/index.php?topic=3023.0:

    myScrollView.maximumZoomScale = 4.0;
    myScrollView.minimumZoomScale = 0.25;

    Un peu perdu quand même dans tout ca...
  • CéroceCéroce Membre, Modérateur
    08:00 modifié #4
    Bon je voulais télécharger le SDK iPhone pour pouvoir te répondre, on va faire sans pour cette fois, mais je ne garantis pas que ça marche. Je te laisse te débrouiller pour faire les remplacements où il convient.

    Bon, déjà , je vois pas pourquoi tu as défini des propriétés scrollView1 et 2. Les propriétés servent à  accéder aux variables d'instance.

    Pour le code, ça doit donner quelque chose comme ça:

    @interface MyViewController : UIViewController {<br />	IBOutlet UIScrollView *scrollView1;<br />	IBOutlet UIScrollView *scrollView2;<br />	<br />	IBOutlet UIImageView*	imageView;	// Configurée pour que l&#39;image remplisse toute la vue (Scale Proportionally)<br />	float zoomFactor;<br />}<br /><br />- (IBAction) zoomChanged:(id)sender;<br /><br />- (void) setImage:(UIImage*)image;<br />- (void) _setImageViewSize:(NSSize)size;<br /><br /><br />@end
    


    J'ai ajouté:
    - une outlet vers les UIImageView préalablement glissée dans la scrollview. La vie est trop courte pour écrire du code.
    - une action pour changer le zoom. À relier par exemple à  un slider dont les valeurs vont de 0,25 à  4.



    Et le .m:

    - (id) init<br />{	<br />	if(self = [super init])<br />	{<br />		zoomFactor = 1.0;	<br />	}<br />	<br />	return self;<br />}<br /><br /><br />- (void)viewDidLoad<br />{<br />	[scrollView1 setScrollEnabled:YES];<br />	[self setImage:[UIImage imageNamed:@&quot;GUAD.tif&quot;]];<br />}<br /><br />- (void) setImage:(UIImage*)image<br />{<br />	[self _setImageViewSize:[image size]];<br />	[imageView setImage:image];<br />}<br /><br />- (IBAction) zoomChanged:(id)sender<br />{<br />	zoomFactor = [sender floatValue];<br />	[self&nbsp; _setImageViewSize:[[imageView image] size]];<br />}<br /><br /><br />- (void) _setImageViewSize:(NSSize)size<br />{<br />	NSSize zoomedSize = NSMakeSize([image size].width * zoomFactor, [image size].height * zoomFactor);<br />	// Faut-il appeler ici [scrollView1 setContentSize: zoomedSize] ???<br />	[imageView setFrameSize: zoomedSize];	<br />}
    


    La partie intéressante se trouve dans la dernière méthode. Il faut prendre les dimensions de l'image, les multiplier par le facteur de zoom, et donner cette taille à  la UIImageView. Comme tu l'as réglée sous IB pour que l'image la remplisse entièrement, ça te fait un beau zoom.
    Je pense que la scrollview s'adapte automatiquement à  son contenu; il n'est donc sans doute pas nécessaire de décommenter la 3ème ligne.
  • stounfrstounfr Membre
    08:00 modifié #5
    Ok merci pour le code,

    alors lorsque je mets ce que tu as mis, j'ai une erreur.

    Dans mon .m
    <br /><br /><br />#import &quot;MyViewController.h&quot;<br /><br />@implementation MyViewController<br /><br />@synthesize scrollView1, scrollView2;<br /><br />- (id) init<br />{<br />	if(self = [super init])<br />	{<br />		zoomFactor = 1.0;<br />	}<br />	return self;<br />}<br /><br /><br />- (void)viewDidLoad<br />{<br />	self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];<br /><br />	[scrollView1 setScrollEnabled:YES];<br />	scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;<br />	[self setImage:[UIImage imageNamed:@&quot;GUAD.tif&quot;]];<br /><br />}<br /><br />- (void) setImage:(UIImage*)image<br />{<br />	[self _setImageViewSize:[image size]];<br />	[imageView setImage:image];<br />}<br /><br />- (IBAction) zoomChanged:(id) sender<br />{<br />	zoomFactor = [sender floatValue];<br />	[self _setImageViewSize:[[imageView image] size]];<br />}<br /><br />- (void) _setImageViewSize:(NSSize)size<br />{<br />	NSSize zoomedSize = NSMakeSize([image size].width * zoomFactor, [image size].height * zoomFactor);<br />	// Faut-il appeler ici [scrollView1 setContentSize: zoomedSize]<br />	[imageView setFrameSize : zoomedSize];<br />}<br /><br />- (void)dealloc<br />{	<br />	[scrollView1 release];<br />	[scrollView2 release];<br />	<br />	[super dealloc];<br />}<br /><br />- (void)didReceiveMemoryWarning<br />{<br />	// invoke super&#39;s implementation to do the Right Thing, but also release the input controller since we can do that	<br />	// In practice this is unlikely to be used in this application, and it would be of little benefit,<br />	// but the principle is the important thing.<br />	//<br />	[super didReceiveMemoryWarning];<br />}<br /><br />@end<br />
    


    L'erreur qui m'est retourné (j'en ai 3) :

    /Users/stoun/Desktop/test/Classes/MyViewController.m:31: error: incompatible type for argument 1 of '_setImageViewSize:'
    /Users/stoun/Desktop/test/Classes/MyViewController.m:38: error: incompatible type for argument 1 of '_setImageViewSize:'
    /Users/stoun/Desktop/test/Classes/MyViewController.m:43: error: 'image' undeclared (first use in this function)

    Stoun
  • Philippe49Philippe49 Membre
    novembre 2008 modifié #6
    type CGSize sous iPhone SDK, pas NSSize
  • stounfrstounfr Membre
    08:00 modifié #7
    Ok Merci Philippe49 pour le type, mais cela ne fonctionne toujours pas.
    :crackboom:-
    Stoun
  • Philippe49Philippe49 Membre
    novembre 2008 modifié #8
    dans 1228008982:

    Ok Merci Philippe49 pour le type, mais cela ne fonctionne toujours pas.

    Cela a du te faire disparaà®tre au moins les deux premiers messages d'erreur ?
    Bon, précise ce qui "ne fonctionne pas" : encore des messages d'erreurs, exécution non conforme, ...

    Vérifications
    Vérifie si l'image est bien prise en compte
    UIImage * image=[UIImage imageNamed:@GUAD.tif];
    NSLog(@%@",image);

    puis que l'imageView est bien connectée, ainsi que les scroll view
    NSLog(@%@",imageView);
  • AliGatorAliGator Membre, Modérateur
    08:00 modifié #9
    Sans rentrer plus dans les détails que cela, je n'ai pas fait de tests plus poussés, mais je me souviens avoir essayé de régler le minimum/maximumZoomScale pensant que ça allait gérer le zoom tout seul d'après les taps sur l'écran, mais apparemment ça n'avait pas suffi non plus...

    That was my two cents, après j'ai pas regardé en détail le reste du code ici...
  • Eddy58Eddy58 Membre
    08:00 modifié #10
    Un tutoriel intéressant ici
  • LastikoLastiko Membre
    08:00 modifié #11
    ah tiens une UIScroolView chouette

    perso je me demande surtout comment on peut faire un ZoomOut ( je voudrais revenir a la position initiale )
    mais je vois pas comment on fait

    si quelqu'un a une idée :D
  • Philippe49Philippe49 Membre
    janvier 2009 modifié #12
    dans 1230803053:

    perso je me demande surtout comment on peut faire un ZoomOut ( je voudrais revenir a la position initiale )


    En complétant l'exemple de ce post , et sans sous-classer UIScrollView.


    @synthesize window,myScrollView,myImageView;
    @synthesize initialViewFrame,initialContentSize;


    - (void)applicationDidFinishLaunching:(UIApplication *)application {   
    // loading image
    NSURL * imageURL=[NSURL URLWithString:@"http://www.austinbull.com/clonemines.png"];
    NSData * imageData=[NSData dataWithContentsOfURL:imageURL];
    UIImage * image=[UIImage imageWithData:imageData];
    self.myImageView=[[[UIImageView alloc] initWithImage:image] autorelease];

    // configure scroll view
    self.initialContentSize=myScrollView.contentSize=myImageView.frame.size;
    self.initialViewFrame=myImageView.frame;
    myScrollView.maximumZoomScale=4.0;
    myScrollView.minimumZoomScale=0.5;
    myScrollView.clipsToBounds=YES;
    [myScrollView addSubview:myImageView];
     
        [window makeKeyAndVisible];
    }

    -(IBAction) resetZoomScale:(id) sender{   
    NSLog(@zooming out);
    UIView *view = [(id<UIScrollViewDelegate>)[myScrollView delegate]  viewForZoomingInScrollView:myScrollView];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.4];

    myScrollView.contentSize = initialContentSize;
    view.frame= initialViewFrame;

    [myScrollView scrollRectToVisible:CGRectMake(0.,0.,myScrollView.frame.size.width,myScrollView.frame.size.height) animated:YES];
    [UIView commitAnimations];
    }


  • LastikoLastiko Membre
    08:00 modifié #13
    Bonjour Philippe

    M'en vais Tester ca tout de suite :P
  • LastikoLastiko Membre
    08:00 modifié #14
    Philou tu peux joindre ton projet stp ?
    J.
  • Philippe49Philippe49 Membre
    février 2009 modifié #15
    Voilou
  • LastikoLastiko Membre
    08:00 modifié #16
    Merci Beaucoup

    je t'adore :P

    John
  • SunSeekerSunSeeker Membre
    janvier 2009 modifié #17
  • Philippe49Philippe49 Membre
    08:00 modifié #18
    Je te propose d'ouvrir un nouveau fil de discussion par question, en la formulant précisément, parce que là  je ne sais pas si c'est l'heure mais on a du mal à  s'y retrouver ...

    en attendant , Bienvenu sur le site !
Connectez-vous ou Inscrivez-vous pour répondre.