Clasa UIGestureRecognizer ușurează detectarea și reacția la gesturi complexe într-o aplicație SDK iOS. Acest tutorial vă va învăța cum să utilizați clasa UIGestureRecognizer demonstrând cum să construiți o bibliotecă simplă de galerie foto.
UIGestureRecognizer a fost disponibil de la iOS 3.2. Cu toate acestea, s-ar putea să fiți surprinși să aflați că rareori veți lucra direct cu această clasă. În schimb, veți implementa una din mai multe subclase concepute pentru a răspunde la anumite gesturi de atingere. Următoarele subclase UIGestureRecognizer sunt livrate împreună cu SDK-ul iOS:
În acest tutorial vom face o galerie foto simplă. Mai întâi veți vedea o listă cu produse de la Apple. Dacă selectați una, veți vedea o imagine a produsului respectiv. Puteți să măriți, rotiți, mutați și să resetați imaginea la starea implicită cu gesturi.
În plus față de utilizarea gesturilor predefinite enumerate mai sus, puteți, de asemenea, utilizați subclasa UIGestureRecognizer, astfel încât să puteți crea și detecta propriile dvs. gesturi personalizate, cum ar fi un semn de selectare sau un cerc. Nu vom face asta în acest tutorial, dar puteți găsi mai multe informații despre el în documentația Apple.
Deschideți Xcode și selectați "Creați un nou proiect Xcode". Selectați o aplicație Master-Detail și faceți clic pe Următorul. Introduceți un nume pentru proiectul dvs., i-am sunat pe "Galerie foto". Introduceți identificatorul companiei și asigurați-vă că ați selectat iPhone pentru familia de dispozitive, pentru că vom face o aplicație iPhone. De asemenea, asigurați-vă că toate casetele de selectare sunt selectate, cu excepția casetei de selectare Utilizați datele de bază. După cum puteți vedea, vom folosi noile caracteristici iOS 5 Storyboard și funcții de numărare automată a referințelor (ARC) în acest tutorial. Dacă ați terminat, faceți clic pe Următorul. Alegeți un loc pentru salvarea proiectului și faceți clic pe Creați.
Deoarece folosim storyboard-uri în loc de fișiere în acest tutorial, nu veți vedea MainWindow.xib, ci un fișier numit MainStoryboard.storyboard. Când deschideți acest fișier, veți vedea întreaga interfață de utilizator, care conține un controler de navigare și două controale de vizualizare.
Dacă selectați segue (arrow) între cele două controale de vizualizare, veți vedea că celula de vizualizare a tabelului se aprinde. Aceasta înseamnă că primul controler de vizualizare va împinge cel de-al doilea controler de vizualizare. Dacă selectați celula de vizualizare a tabelului, nu va trebui să sunăm pushViewController:
mai.
De asemenea, aruncați o privire la fișierul MasterViewController.m. Veți vedea că nu există dealloc
metodă. Acest lucru se datorează faptului că folosim ARC, iar ARC se ocupă de metodele legate de memorie reține
, eliberare
, AutoreleasePool
și dealloc
pentru noi.
Acum, construiți și executați proiectul. Ar trebui să vedeți un controler de navigare cu titlul Master și o celulă numită Detaliu. Când selectați această celulă, veți fi împins la cel de-al doilea controler de vizualizare care arată un anumit text.
Deschideți MasterViewController.h și modificați codul după cum urmează:
#import#import "DetailViewController.h" @interface MasterViewController: UITableViewController lista NSArray *; @property (puternic, nonatomic) NSArray * list; @Sfârșit
Aici vom importa clasa DetailViewController și vom crea o listă numită matrice.
Acum mergeți la MasterViewController.m și adăugați următoarele linii sub @implementation:
@ syntesize list;
Acum derulați până la viewDidLoad
și modificați codul după cum urmează:
- (vid) viewDidLoad [super viewDidLoad]; self.title = @ "Produse"; NSArray * listArray = [[NSArray alocare] initWithObjects: @ "iPhone", @ "iPad", @ "iMac", @ "MacBook Air", nil]; self.list = listArray;
Aici am setat titlul barei de navigare la "produse" și creăm o matrice falsă cu produsele Apple pentru a umple matricea noastră de listă. Nu trebuie să lansăm listaArray, deoarece ARC va face asta pentru noi.
Acum du-te la shouldAutorotateToInterfaceOrientation:
și modificați codul după cum urmează, astfel încât aplicația noastră să funcționeze numai în portret:
- (BOOL) ar trebui să autorizezeTointerfaceOrientation: (UIInterfaceOrientation) interfaceOrientation return (interfaceOrientation == UIInterfaceOrientationPortrait);
Acum adăugați următoarele metode sursă de date din tabelă shouldAutorotateToInterfaceOrientation:
metodă:
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView retur 1; - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectiunea return [numar lista] ;; - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * CellIdentifier = @ "Celula"; UITableViewCell * celula = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; cell.textLabel.text = [list objectAtIndex: [indexPath row]]; celule retur;
Aici setăm numărul de secțiuni ale vizualizării tabelului la 1 și numărul de rânduri din secțiunea respectivă la numărul de obiecte din matricea noastră de liste. Am setat textul celulelor în vizualizarea de tabelă la produsele din matricea noastră de liste.
În sfârșit, adăugați următoarea metodă sub metodele sursă de date din tabelul de vizualizare:
- (void) prepareForSegue: (UIStoryboardSegue *) expeditor segue: (id) expeditor [segue.destinationViewController setProductName: [list objectAtIndex: [self.tableView.indexPathForSelectedRow row]]];
Aici treceți șirul de nume de produs la controlerul de vizualizare detaliat. Vom folosi acest șir pentru titlul barei de navigare și pentru a seta imaginea. Veți primi o eroare, deoarece încă nu am definit șirul de produsName în DetailViewController. Tabloul de bord va numi această metodă la timpul de execuție când declanșezi o segheră în scena curentă.
Ultimul lucru pe care trebuie să-l facem este să ne actualizăm tabelul în tabloul de scripturi, așa că deschideți "MainStoryboard.storyboard" și selectați tabelul. Deschideți Inspectorul atributelor și modificați conținutul din celule statice la prototipuri dinamice.
Acum, selectați celula de vizualizare a tabelului și setați identificatorul la celulă. De asemenea, setați indicatorul Accesoriu la dezvăluire.
După cum puteți vedea, segmentele dintre cele două controlere de vizualizare au dispărut. Acest lucru se datorează faptului că am modificat vizualizarea tabelului. Pentru a adăuga din nou această problemă, CTRL trageți de la tabelă la DetailViewController și selectați Push for Segues Storyboard.
Deschideți MainStoryboard.storyboard, selectați eticheta din ultimul controler de vizualizare și ștergeți-l. Trageți acum un UIImageView în vizualizare și faceți ca acesta să umple întregul spațiu. În Inspectorul de atribute setați Modul de afișare a imaginii la Aspect Fit.
Acum trebuie doar să conectăm vizualizarea imaginii, deci selectați butonul din mijloc al editorului pentru a afișa "Editorul asistent".
Selectați vizualizarea imaginilor și controlați-le în sub declarația @Interface pentru DetailViewController. Va apărea un pop-up. Introduceți "productImageView" pentru câmpul nume, setați tipul de stocare la puternic și faceți clic pe Conectare.
Deschideți DetailedViewController.h și modificați codul după cum urmează:
#import@interface DetailViewController: UIViewController NSString * productName; CGFloat previousScale; CGFloat previousRotation; CGFloat beginX; CGFloat începe; @property (puternic, nonatomic) IBOutlet UIImageView * productImageView; @property (puternic, nonatomic) NSString * productName; @Sfârșit
Aici, creăm câteva variabile pe care le vom folosi pentru a ajusta imaginea. De asemenea, creăm numele produsului
Șir despre care am vorbit mai devreme.
Acum mergeți la fișierul DetailViewController.m și ștergeți următoarele rânduri:
@synthesize detailItem = _detailItem; @synthesize detailDescriptionLabel = _detailDescriptionLabel;
Ștergeți, de asemenea, aceste linii și setDetailItem:
și configureView
metode:
@interface DetailViewController () - (void) configureView; @Sfârșit
acum adăugați următoarea linie sub @implementation:
@synthesize productName;
Mergeți la shouldAutorotateToInterfaceOrientation:
metodă și modificați codul pentru a citi după cum urmează, astfel încât aplicația noastră va funcționa și în acest vizualizator doar în portret:
- (BOOL) ar trebui să autorizezeTointerfaceOrientation: (UIInterfaceOrientation) interfaceOrientation return (interfaceOrientation == UIInterfaceOrientationPortrait);
Mai întâi trebuie să adăugăm imaginile la proiectul nostru, pentru a descărca exemplul de cod atașat la acest proiect și trageți imaginile iMac, iPad, iPhone și MacBook Air în proiectul dvs. Asigurați-vă că este bifată opțiunea "Copiați articolele în folderul grupului de destinație (dacă este necesar)", apoi faceți clic pe Terminare.
Acum derulați până la viewDidLoad
în fișierul DetailViewController.m și modificați codul astfel:
- (vid) viewDidLoad [super viewDidLoad]; self.title = productName; NSString * imageName = [NSString șirWithFormat: @ "% @. Jpg", productName]; auto.productImageView.image = [UIImage imageNamed: imageName];
Aici setăm titlul barei de navigare pe produsul selectat și după aceea atribuim imaginea corespunzătoare produsului respectiv în afișarea imaginii.
Acum, construiți și executați aplicația. Ar trebui să vedeți acum o listă de produse Apple. Dacă selectați una, veți merge la următoarea vedere cu o imagine a produsului respectiv.
Mergeți la viewDidLoad
metoda în DetailViewController.m și adăugați următorul cod la acea metodă:
UIRotationGestureRecognizer * rotationGesture = [[UIRotationGestureRecognizer alocare] initWithTarget: acțiune individuală: @selector (rotateImage :)]; [auto.view addGestureRecognizer: rotationGesture];
Aici, am creat recunoașterea gestului de rotație. Acum adaugati rotateImage:
metodă:
- (void) rotateImage: (UIRotationGestureRecognizer *) recunoaștere if ([recognizer state] == UIGestureRecognizerStateEnded) previousRotation = 0.0; întoarcere; CGFloat newRotation = 0.0 - (precedentRotație - [rotație recunoaștere]); CGAffineTransform currentTransformation = auto.productImageView.transform; CGAffineTransform newTransform = CGAffineTransformRotate (actualTransformare, nouăRotare); self.productImageView.transform = newTransform; previousRotation = [rotația recunoașterii];
În această metodă, verificăm mai întâi dacă gesturile de rotație au încetat. Dacă este cazul, am setat valoarea precedentăRotație la 0. Apoi, calculăm noua rotație cu rotația anterioară și apoi setăm rotația curentă. Acest lucru se face astfel încât rotația următoare va începe cu rotația curentă. Vrem să aplicăm această rotație transformării actuale. Deci, obținem transformarea noastră actuală și adăugăm rotația la ea. În cele din urmă, am setat precedentul rotație la rotația curentă a degetelor.
Mergeți la viewDidLoad
și adăugați următorul cod la această metodă:
UIPinchGestureRecognizer * pinchGesture = [[UIPinchGestureRecognizer alocare] initWithTarget: acțiune auto: @selector (scaleImage :)]; [auto.view addGestureRecognizer: pinchGesture];
Aici creăm recunoașterea gestului de împingere. Acum adaugati scaleImage:
metodă:
- (void) scaleImage: (recunoașterea UIPinchGestureRecognizer *) if ([recognizer state] == UIGestureRecognizerStateEnded) previousScale = 1.0; întoarcere; CGFloat newScale = 1.0 - (precedentScale - [scara recunoașterii]); CGAffineTransform currentTransformation = auto.productImageView.transform; CGAffineTransform newTransform = CGAffineTransformScale (actualTransformare, newScale, newScale); self.productImageView.transform = newTransform; previousScale = [scara recunoașterii];
Această metodă este foarte similară cu metoda rotateImage, dar în loc de rotire a imaginii, vom scala imaginea.
Mergeți la viewDidLoad
și adăugați următorul cod la această metodă:
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alocare] initWithTarget: actiune auto: @selector (resetImage :)]; [self.view addGestureRecognizer: tapGesture];
Aici am creat recunoașterea gestului de atingere. Acum adaugati scaleImage:
metodă:
- (void) resetImage: (UITapGestureRecognizer *) recunoaștere [UIView beginAnimations: context zero: zero]; [Durata de desfășurare a activării: 0.3]; self.productImageView.transform = CGAffineTransformIdentity; [auto.productImageView setCenter: CGPointMake (auto.view.frame.size.width / 2, self.view.frame.size.height / 2)]; [Afișează comenziAnimații];
În această metodă, resetați imaginea la starea implicită cu o animație plăcută. Centralizăm imaginea și eliminăm transformările.
Pentru ultima oară, mergeți la viewDidLoad
și adăugați următorul cod la această metodă:
UIPanGestureRecognizer * panGesture = [[UIPanGestureRecognizer alocare] initWithTarget: actiune auto: @selector (moveImage :)]; [setatManimumNumberOfTouches: 1]; [set de panGestretimă maximă număr: 1]; [auto.view addGestureRecognizer: panGesture];
Aici am creat recunoașterea gestului pentru gesturi. Am setat proprietatea minimNumberOfTouches și maximumNumberOfTouches la 1, deci acest gest va funcționa numai cu un deget. Acum adaugati moveImage:
metodă:
- (void) moveImage: (UIPanGestureRecognizer *) recunoaștere CGPoint newCenter = [recognizer translationInView: self.view]; dacă ([recognizer state] == UIGestureRecognizerStateBegan) beginX = self.productImageView.center.x; beginY = self.productImageView.center.y; newCenter = CGPointMake (începutX + newCenter.x, beginY + newCenter.y); [auto.productImageView setCenter: newCenter];
Aici vom crea un CGPoint și vom seta valoarea la locația degetului. Dacă începem cu gestul pan. Am setat valoarea variabilelor beginX și beginY la coordonatele x și y din centrul vederii imaginii. După aceea, se calculează noile coordonate pentru centrul vederii imaginii, astfel încât centrul vederii imaginii va fi în același loc cu degetul nostru. În sfârșit, am setat centrul afișării de imagini la noulCenter CGPoint pe care tocmai l-am calculat.
Rulați aplicația din nou și de această dată aveți posibilitatea să rotiți, să măriți și să mutați imaginea. Dacă atingeți imaginea, imaginea va merge la starea implicită.
Sper că ți-a plăcut acest tutorial despre gesturi. Dacă aveți câteva idei noi pentru tutorialele iOS, lăsați-le în secțiunea de comentarii de mai jos!