Bouw een eenvoudige fotogalerij met UIGestureRecognizer

Met de klasse UIGestureRecognizer kunt u complexe gebaren in een iOS SDK-toepassing gemakkelijk detecteren en erop reageren. Deze tutorial leert je hoe je de UIGestureRecognizer-klasse gebruikt door te demonstreren hoe je een eenvoudige bibliotheek met fotogalerieën maakt.

De UIGestureRecognizer is beschikbaar sinds iOS 3.2. Het zal je echter misschien verbazen dat je zelden direct met deze klas zult werken. In plaats daarvan implementeert u een van de verschillende subklassen die zijn ontworpen om te reageren op specifieke aanraakbewegingen. De volgende UIGestureRecognizer-subklassen worden geleverd met de iOS SDK:

        
  • UITapGestureRecognizer: Zoekt naar enkele of meerdere tikken. Deze beweging wordt herkend als een bepaald aantal vingers een bepaald aantal keer binnen een vooraf gedefinieerde tijdsbestek op een weergave tikt.
  • UIPinchGestureRecognizer: Zorgt voor knijpende bewegingen. Wanneer de gebruiker twee vingers naar elkaar toe beweegt, wordt de actie "uitzoomen" geactiveerd en als de gebruiker twee vingers van elkaar weg beweegt, wordt de actie "inzoomen" geactiveerd.
  • UIRotationGestureRecognizer: Zoekt rotatiebewegingen. Als de gebruikers hun vingers in een cirkelvormige beweging bewegen, moet het onderliggende beeld in dezelfde richting en snelheid draaien.
  • UISwipeGestureRecognizer: Zoekt naar bewegingen in één of meerdere richtingen. Een veegbeweging is een afzonderlijk gebaar, dus de bijbehorende methode wordt slechts één keer per veegbeweging aangeroepen.
  • UIPanGestureRecognizer: Zoekt naar slepende bewegingen. De gebruikers moeten een of meer vingers in een weergave indrukken terwijl ze deze slepen.
  • UILongPressGestureRecognizer: Zoekt naar lange-drukbewegingen. De gebruikers moeten een of meer vingers op een weergave indrukken voor een langere periode voordat de methode wordt aangeroepen. Als uw vingers een opgegeven afstand verplaatsen terwijl u ingedrukt houdt, mislukt het gebaar.

In deze tutorial zullen we een eenvoudige fotogalerij maken. Eerst ziet u een lijst met producten van Apple. Als u er een selecteert, ziet u een afbeelding van dat product. U kunt met gebaren naar de standaardstatus zoomen, draaien, verplaatsen en opnieuw instellen.

Naast het gebruik van de hierboven opgesomde voorgedefinieerde bewegingen, kunt u ook UIGestureRecognizer zelf subclassificeren, zodat u uw eigen aangepaste bewegingen, zoals een vinkje of een cirkel, kunt maken en detecteren. We zullen dit niet doen in deze tutorial, maar je kunt er meer informatie over vinden in de Apple-documentatie.


Stap 1: Het project maken

Open Xcode en selecteer "Een nieuw Xcode-project maken". Selecteer een Master-Detail-toepassing en klik op Volgende. Voer een naam in voor uw project, ik heb de mijne "Fotogalerij" genoemd. Voer je bedrijfsidentificatie in en zorg ervoor dat je de iPhone hebt geselecteerd voor Device Family, want we gaan een iPhone-app maken. Zorg er ook voor dat alle selectievakjes zijn geselecteerd, behalve het selectievakje Kerngegevens gebruiken. Zoals u kunt zien, zullen we de nieuwe iOS 5 Storyboard en Automatic Reference Counting (ARC) -functies in deze zelfstudie gebruiken. Als u klaar bent, klikt u op Volgende. Kies een plaats om uw project op te slaan en klik op Maken.

    

Omdat we in deze zelfstudie storyboards gebruiken in plaats van nib-bestanden, ziet u het MainWindow.xib niet, maar een bestand met de naam MainStoryboard.storyboard. Wanneer u dit bestand opent, ziet u de volledige gebruikersinterface, die een navigatiecontroller en twee view-controllers bevat.

    

Als u de segue (pijl) selecteert tussen de twee beeldcontrollers, ziet u dat de cel voor de tabelweergave oplicht. Dit betekent dat de eerste beeldcontroller de tweede beeldcontroller zal duwen. Als u de tabelweergavecel selecteert, hoeven we niet te bellen pushViewController: meer.

Bekijk ook het MasterViewController.m-bestand. Je zult zien dat er geen is dealloc methode. Dit komt omdat we ARC gebruiken en ARC omgaat met geheugengerelateerde methoden zoals behouden, vrijlating, autorelease en dealloc voor ons.

Bouw en run nu het project. U zou een navigatiecontroller moeten zien met de titel Master en een cel met de naam Detail. Wanneer u deze cel selecteert, wordt u naar de tweede weergavecontroller geduwd die wat tekst weergeeft.


Stap 2: Stel de tabweergave in

Open MasterViewController.h en pas de code als volgt aan:

 #importeren  #import "DetailViewController.h" @interface MasterViewController: UITableViewController NSArray * list;  @property (strong, nonatomic) NSArray * lijst; @einde

Hier importeren we de klasse DetailViewController en maken we een arraylijst genaamd.

Ga nu naar MasterViewController.m en voeg de volgende regels toe onder de @implementation:

 @synthesize lijst;

Blader nu naar beneden naar de viewDidLoad methode en wijzig de code om deze als volgt te lezen:

 - (void) viewDidLoad [super viewDidLoad]; self.title = @ "Producten"; NSArray * listArray = [[NSArray alloc] initWithObjects: @ "iPhone", @ "iPad", @ "iMac", @ "MacBook Air", niets]; self.list = listArray; 

Hier stellen we de titel van de navigatiebalk in op "producten" en creëren we een dummy-array met Apple-producten om onze lijstmatrix te vullen. We hoeven de listArray niet vrij te geven, omdat ARC dat voor ons zal doen.

Ga nu naar de shouldAutorotateToInterfaceOrientation: methode en wijzig de code om ze als volgt te lezen, dus onze applicatie werkt alleen in portret:

 - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation return (interfaceOrientation == UIInterfaceOrientationPortrait); 

Voeg nu de volgende tabelweergave-gegevensbronmethoden toe onder de shouldAutorotateToInterfaceOrientation: methode:

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView return 1;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectie return [lijsttelling] ;;  - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath static NSString * CellIdentifier = @ "Cell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; cell.textLabel.text = [list objectAtIndex: [rij van indexpad]]; terugkeer cel; 

Hier stellen we het aantal secties van de tabelweergave in op 1 en het aantal rijen van die sectie op het aantal objecten in onze lijstreeks. We plaatsen de tekst van de cellen in de tabelweergave voor de producten in ons lijst array.

Voeg ten slotte de volgende methode toe in de tabelweergave van de gegevensbronmethoden:

 - (void) prepareForSegue: (UIStoryboardSegue *) segue verzender: (id) afzender [segue.destinationViewController setProductName: [list objectAtIndex: [self.tableView.indexPathForSelectedRow row]]]; 

Hier geven we onze productnaamstring door aan de detailaanzichtcontroller. We zullen deze string gebruiken voor de titel van de navigatiebalk en om de afbeelding in te stellen. U krijgt een foutmelding, omdat we de productnaam-string in de DetailViewController nog niet hebben gedefinieerd. Het storyboard roept deze methode tijdens runtime aan wanneer u een segue in de huidige scène activeert.

Het laatste wat we moeten doen is onze tableview bijwerken in het storyboard, dus open "MainStoryboard.storyboard" en selecteer de tabweergave. Open de Attributen Inspector en verander de inhoud van statische cellen naar dynamische prototypen.

    

Selecteer nu de tabelweergavecel en stel de ID in op Cel. Stel ook de indicator Accessoire voor onthulling in.

    

Zoals u kunt zien, is de segue tussen de twee view controllers verdwenen. Dit komt omdat we de tabelweergave hebben gewijzigd. Om deze segue opnieuw toe te voegen, sleept CTRL van de tabweergave naar de DetailViewController en selecteert u Push voor de storyboard-segmenten.


Stap 3: De interface maken

Open het MainStoryboard.storyboard, selecteer het label in de laatste view controller en verwijder het. Sleep nu een UIImageView naar de weergave en laat hem de hele ruimte vullen. Stel in de Attributen Inspector de modus van de afbeelding in op Aspect Fit.

Nu hoeven we alleen de beeldweergave aan te sluiten, dus selecteer de middelste knop van de Editor om de "Assistent-editor" weer te geven.

    

Selecteer de afbeeldingsweergave en sleep en sleep naar onder de instructie DetailViewController @interface. Er verschijnt een pop-up. Voer "productImageView" in voor het veld naam, stel het opslagtype in op strong en klik op Verbinden.

    

Stap 4: Sommige variabelen maken

Open DetailViewController.h en pas de code als volgt aan:

 #importeren  @interface DetailViewController: UIViewController NSString * productName; CGFloat vorigeScale; CGFloat vorigeRotation; CGFloat beginX; CGFloat beginY;  @property (strong, nonatomic) IBOutlet UIImageView * productImageView; @property (strong, nonatomic) NSString * productName; @einde

Hier maken we enkele variabelen die we zullen gebruiken om de afbeelding aan te passen. We maken ook de productnaam string waar we eerder over gesproken hebben.

Ga nu naar het DetailViewController.m-bestand en verwijder de volgende regels:

 @synthesize detailItem = _detailItem; @synthesize detailDescriptionLabel = _detailDescriptionLabel;

Verwijder ook deze regels en de setDetailItem: en configureView methoden:

 @interface DetailViewController () - (void) configureView; @einde

voeg nu de volgende regel toe onder de @implementation:

 @synthesize productName;

Stap 5: Verander de oriëntatie

Ga naar de shouldAutorotateToInterfaceOrientation: methode en wijzig de code om deze als volgt te lezen, dus onze applicatie zal ook in deze weergave-controller alleen in portret werken:

 - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation return (interfaceOrientation == UIInterfaceOrientationPortrait); 

Stap 6: De afbeeldingen toevoegen

Eerst moeten we de afbeeldingen toevoegen aan ons project, dus download de voorbeeldcode die aan dit project is gekoppeld en sleep de iMac-, iPad-, iPhone- en MacBook Air-afbeeldingen naar uw project. Zorg ervoor dat "Items in de map van de bestemmingsgroep kopiëren (indien nodig)" is aangevinkt en klik vervolgens op Voltooien.

    

Blader nu naar beneden naar de viewDidLoad methode in het DetailViewController.m-bestand en pas de code aan om deze als volgt te lezen:

 - (void) viewDidLoad [super viewDidLoad]; self.title = productName; NSString * imageName = [NSString stringWithFormat: @ "% @. Jpg", productName]; self.productImageView.image = [UIImage imageNamed: imageName]; 

Hier stellen we de titel van de navigatiebalk in op het geselecteerde product en daarna wijzen we de bijbehorende afbeelding van dat product toe aan de beeldweergave.

Bouw de applicatie nu en voer hem uit. Je zou nu een lijst met Apple-producten moeten zien. Als u er een selecteert, gaat u naar de volgende weergave met een afbeelding van dat product.

    

Stap 7: UIRotationGestureRecognizer

Ga naar de viewDidLoad methode in DetailViewController.m en voeg de volgende code toe aan die methode:

 UIRotationGestureRecognizer * rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget: self action: @selector (rotateImage :)]; [self.view addGestureRecognizer: rotationGesture];

Hier hebben we de rotatie-gebaarherkenner gemaakt. Voeg nu de rotateImage: methode:

 - (void) rotateImage: (UIRotationGestureRecognizer *) herkenning if ([herkenningsstatus] == UIGestureRecognizerStateEnded) previousRotation = 0.0; terug te keren;  CGFloat newRotation = 0.0 - (previousRotation - [herkenner rotatie]); CGAffineTransform currentTransformation = self.productImageView.transform; CGAffineTransform newTransform = CGAffineTransformRotate (currentTransformation, newRotation); self.productImageView.transform = newTransform; previousRotation = [herkenner rotatie]; 

In deze methode controleren we eerst of de rotatiebewegingen zijn beëindigd. Als dit het geval is, stellen we de vorigeRotatiewaarde in op 0. Vervolgens berekenen we de nieuwe rotatie met de vorige rotatie en stellen we de huidige rotatie in. Dit wordt gedaan zodat onze volgende rotatie begint met de huidige rotatie. We willen deze rotatie toepassen op de huidige transformatie. Dus we krijgen onze huidige transformatie en voegen er de rotatie aan toe. Eindelijk stellen we de vorigeRotationValue in op de huidige rotatie van uw vingers.


Stap 8: UIPinchGestureRecognizer

Ga naar de viewDidLoad methode en voeg de volgende code toe aan die methode:

 UIPinchGestureRecognizer * pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget: self action: @selector (scaleImage :)]; [self.view addGestureRecognizer: pinchGesture];

Hier maken we de knijpgebaar-herkenner. Voeg nu de scaleImage: methode:

 - (void) scaleImage: (UIPinchGestureRecognizer *) herkenner if ([herkenningsstatus] == UIGestureRecognizerStateEnded) previousScale = 1.0; terug te keren;  CGFloat newScale = 1.0 - (previousScale - [recognizer scale]); CGAffineTransform currentTransformation = self.productImageView.transform; CGAffineTransform newTransform = CGAffineTransformScale (currentTransformation, newScale, newScale); self.productImageView.transform = newTransform; previousScale = [herkenningsschaal]; 

Deze methode lijkt veel op de methode rotateImage, maar in plaats van de afbeelding te draaien, schalen we de afbeelding.


Stap 9: UITapGestureRecognizer

Ga naar de viewDidLoad methode en voeg de volgende code toe aan die methode:

 UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector (resetImage :)]; [self.view addGestureRecognizer: tapGesture];

Hier hebben we de tikgebaarherkenner gemaakt. Voeg nu de scaleImage: methode:

 - (void) resetImage: (UITapGestureRecognizer *) herkenner [UIView beginAnimations: nil context: nil]; [UIView setAnimationDuration: 0.3]; self.productImageView.transform = CGAffineTransformIdentity; [self.productImageView setCenter: CGPointMake (self.view.frame.size.width / 2, self.view.frame.size.height / 2)]; [UIView commitAnimations]; 

In deze methode herstellen we de afbeelding naar de standaardstatus met een leuke animatie. We centreren het beeld en verwijderen de transformaties.


Stap 10: UIPanGestureRecognizer

Ga voor de laatste keer naar de viewDidLoad methode en voeg de volgende code toe aan die methode:

 UIPanGestureRecognizer * panGesture = [[UIPanGestureRecognizer alloc] initWithTarget: self action: @selector (moveImage :)]; [panGesture setMinimumNumberOfTouches: 1]; [panGesture setMaximumNumberOfTouches: 1]; [self.view addGestureRecognizer: panGesture];

Hier hebben we de pan-gestureherkenner gemaakt. We hebben de eigenschap minimumNumberOfTouches en maximumNumberOfTouches ingesteld op 1, dus deze beweging werkt alleen met 1 vinger. Voeg nu de moveImage: methode:

 - (void) moveImage: (UIPanGestureRecognizer *) herkenner CGPoint newCenter = [herkenner translationInView: self.view]; if ([herkenningsstatus] == UIGestureRecognizerStateBegan) beginX = self.productImageView.center.x; beginY = self.productImageView.center.y;  newCenter = CGPointMake (beginX + newCenter.x, beginY + newCenter.y); [self.productImageView setCenter: newCenter]; 

Hier maken we een CGPoint en stellen de waarde in op de locatie van uw vinger. Als we beginnen met het pan-gebaar. We stellen de waarde van de beginX- en beginY-variabelen in op de x- en y-coördinaten van het midden van de afbeelding. Daarna berekenen we de nieuwe coördinaten voor het midden van het beeld, zodat het midden van het beeld op dezelfde plaats als onze vinger staat. Eindelijk stellen we het midden van de beeldweergave in op het nieuwe CGPoint dat we net hebben berekend.

Voer de toepassing opnieuw uit en deze keer kunt u de afbeelding draaien, zoomen en verplaatsen. Als u op de afbeelding tikt, wordt de afbeelding naar de standaardstatus gebracht.


Afronden

Ik hoop dat je deze tutorial over gebaren leuk vond. Als je een paar nieuwe ideeën hebt voor iOS-zelfstudie, laat ze dan in de reacties hieronder staan!