Pinch-to-Zoom — den Zwickgestus in mobilen Apps verstehen

Autor: IT Sectr Veröffentlicht: 2026-02-27 Lesezeit: 8 Min.
Pinch-to-Zoom (Fingerzwick) ist ein Multi-Touch-Zoom-Gestus, bei dem der Benutzer zwei Finger auf dem Bildschirm zusammenführt oder spreizt, um den Inhalt zu verkleinern oder zu vergrößern. Dieser Gestus ist zum De-facto-Standard für die Anzeige von Bildern, Karten, Webseiten und Dokumenten auf mobilen Geräten geworden. Laut Apple HIG und Google Material Design ist Pinch-to-Zoom ein grundlegender Gestus, den Benutzer in allen Anwendungen erwarten, die mit visuellen Inhalten arbeiten.

Wichtige Punkte

  • Pinch-to-Zoom ist ein Zwei-Finger-Multi-Touch-Gestus zum Skalieren von Inhalten auf mobilen Geräten.
  • In iOS erfolgt die Verarbeitung über UIPinchGestureRecognizer mit kontinuierlicher Verfolgung von .began → .changed → .ended.
  • Android verwendet ScaleGestureDetector (aus der Support Library) mit dem onScale-Callback, um den Zoom über Matrix zu aktualisieren.
  • UIPinchGestureRecognizer hat die Eigenschaften scale (Verhältnis zum vorherigen Zustand) und velocity (Geschwindigkeit).
  • Um den Zoom zu begrenzen, wird ein Clamp des Skalierungsfaktors zwischen den festgelegten Min-/Max-Werten (normalerweise 0,5–3,0) angewendet.

Was ist Pinch-to-Zoom?

Pinch-to-Zoom (Zwickgestus) ist ein Multi-Touch-Gestus, der zwei Finger verwendet, um den Maßstab des angezeigten Inhalts zu ändern. Beim Zusammenführen der Finger (Pinch Close) verringert sich der Maßstab; beim Spreizen (Pinch Open) erhöht er sich. Der Gestus ist kontinuierlich: Das System verfolgt den Abstand zwischen den Fingern in Echtzeit und erzeugt Zwischenereignisse, sodass die Anwendung den Maßstab fließend aktualisieren kann.

Die Mechanik des Gestus basiert auf der Berechnung des Abstands zwischen zwei Berührungspunkten. iOS und Android verwenden den euklidischen Abstand: sqrt((x2−x1)² + (y2−y1)²). Der aktuelle Maßstab wird als Verhältnis des aktuellen Abstands zum ursprünglichen Abstand berechnet. Wenn der ursprüngliche Abstand 100px betrug und 150px wird — Skalierung = 1,5 (50% Erhöhung). iOS übergibt die Skalierung relativ zum vorherigen Zustand (Delta), Android übergibt die akkumulierte Skalierung über ScaleGestureDetector.

Laut den Google Material Design Guidelines ist Pinch-to-Zoom für Anwendungen, die Bilder, Karten oder Dokumente anzeigen, obligatorisch. Bei IT Sectr implementieren wir diesen Gestus mit UIPinchGestureRecognizer und ScaleGestureDetector in allen Projekten, die mit visuellen Inhalten arbeiten — von Galerien bis hin zu Bildeditoren.

Pinch-to-Zoom in iOS: UIPinchGestureRecognizer

UIPinchGestureRecognizer ist eine kontinuierliche Unterklasse von UIGestureRecognizer zum Erkennen des Zwickgestus. Anders als diskrete Erkennungselemente (UITapGestureRecognizer) erzeugt er eine Ereignissequenz: .began (Finger berühren den Bildschirm), .changed (jede Fingerbewegung), .ended (Finger werden angehoben).

Wichtige Eigenschaften: scale (CGFloat) — relative Änderung des Abstands zwischen den Fingern seit Beginn des Gestus; velocity (CGFloat) — Änderungsrate der Skalierung pro Sekunde. Anfängliche Skalierung = 1,0. Beim Spreizen der Finger steigt die Skalierung (1,0 → 1,5 → 2,0); beim Zusammenführen sinkt sie (1,0 → 0,8 → 0,5). Die Eigenschaft velocity wird für die Trägheit verwendet: Nach .ended kann das fortgesetzte Skalieren mit Verlangsamung animiert werden.

UIPinchGestureRecognizer unterstützt die delegate-Eigenschaft für die gleichzeitige Erkennung mit anderen Erkennungselementen (z. B. Pan + Pinch auf einer Karte). Die Methode gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) gibt true zurück, und beide Gesten arbeiten parallel. Apple empfiehlt, UIPinchGestureRecognizer zur Container-View hinzuzufügen, nicht zu einzelnen Elementen — dies vereinfacht die Berechnung des Pivot-Punkts der Skalierung.

Pinch-to-Zoom in Android: ScaleGestureDetector

ScaleGestureDetector ist eine Klasse aus der Android Support Library (android.view), die für die Erkennung von Multi-Touch-Skalierung entwickelt wurde. Anders als GestureDetector.onFling ist ScaleGestureDetector speziell für den Zwei-Finger-Zoom konzipiert und berechnet automatisch focusX, focusY (den Mittelpunkt zwischen den Fingern) und scaleFactor (Skalierungs-Delta vom vorherigen Ereignis).

ScaleGestureDetector arbeitet über das OnScaleGestureListener-Interface mit drei Methoden: onScaleBegin(detector) (analog zu .began), onScale(detector) (analog zu .changed, gibt boolean zurück — true, wenn die Skalierung akzeptiert wird), onScaleEnd(detector) (analog zu .ended). Eigenschaften: scaleFactor — Skalierungsmultiplikator relativ zum vorherigen Ereignis (~1,01 bei langsamem Spreizen), focusX/focusY — Koordinaten des Mittelpunkts zwischen den Fingern.

Zum Anwenden der Skalierung auf eine View wird normalerweise Matrix verwendet: view.imageMatrix.postScale(scaleFactor, scaleFactor, focusX, focusY). Matrix unterstützt die Akkumulation von Transformationen — jeder postScale-Aufruf fügt eine neue Transformation zur bestehenden hinzu. Wichtig zu beachten: ScaleGestureDetector begrenzt die minimale/maximale Skalierung nicht — das ist die Aufgabe des Entwicklers. Bei IT Sectr verwenden wir ScaleGestureDetector mit benutzerdefinierten Skalierungsgrenzen (0,5–3,0) und einer Rücksetzungsanimation bei Überschreitung.

Zoom-Begrenzung und Pivot-Punkt

Bei der Implementierung von Pinch-to-Zoom ist es entscheidend wichtig, die minimale und maximale Skalierung zu begrenzen — ohne dies kann der Benutzer bis ins Unendliche hineinzoomen oder bis zur Unsichtbarkeit herauszoomen. Standardwerte: min = 0,5 (50% der ursprünglichen Größe), max = 3,0 (300%). Unter iOS erfolgt die Begrenzung über Clamp: newScale = min(max(currentScale * gesture.scale, minScale), maxScale). Unter Android — über eine Prüfung nach postScale.

Der Pivot-Punkt ist der Mittelpunkt zwischen den Fingern, relativ zu dem die Skalierung durchgeführt wird. iOS berechnet automatisch den Schwerpunkt der zwei Berührungen und übergibt ihn über location(in:) — der Entwickler muss den Pivot nicht manuell berechnen. Android stellt focusX/focusY im ScaleGestureDetector bereit, aber bei der Anwendung über Matrix wird der Pivot als drittes und viertes Argument in postScale(scaleFactor, scaleFactor, focusX, focusY) übergeben. Ohne einen Pivot-Punkt erfolgt die Skalierung relativ zur oberen linken Ecke (0,0), was während des Zooms zu einer Verschiebung des Inhalts führt.

Nach Erfahrung von IT Sectr ist die korrekte Berechnung des Pivot-Punkts die häufigste Fehlerquelle bei der Implementierung von Pinch-to-Zoom. In 90% der Fälle reicht es aus, die integrierten Koordinaten von GestureRecognizer und ScaleGestureDetector zu verwenden — kein manuelles Berechnen des Pivots erforderlich. Wenn sich der Inhalt beim Skalieren verschiebt, überprüfen Sie, ob Sie focusX/focusY an matrix.postScale() übergeben.

Trägheit nach dem Zoom

Für eine fließende Benutzererfahrung nach Beendigung des Gestus können Sie Trägheit hinzufügen: unter iOS — verwenden Sie velocity von UIPinchGestureRecognizer mit UIView.animate und Spring-Parametern; unter Android — OverScroller oder ValueAnimator. Die Trägheit sollte die Min-/Max-Skalierungsgrenzen nicht überschreiten — der Endwert wird mit einer Spring-Rücksetzungsanimation bei Überschreitung begrenzt.

Codebeispiele in Swift und Kotlin

Beispiel 1: Pinch-to-Zoom unter iOS (Swift)

Fügt UIPinchGestureRecognizer zu UIImageView mit Skalierungsbegrenzung von 0,5 bis 3,0 hinzu. Zeigt eine minimale Implementierung mit Erhaltung der akkumulierten Skalierung.

swift
import UIKit

class ZoomableImageViewController: UIViewController {

    @IBOutlet private var imageView: UIImageView!
    private var currentScale: CGFloat = 1.0
    private let minScale: CGFloat = 0.5
    private let maxScale: CGFloat = 3.0

    override func viewDidLoad() {
        super.viewDidLoad()

        let pinch = UIPinchGestureRecognizer(
            target: self,
            action: #selector(handlePinch(_:))
        )
        imageView.addGestureRecognizer(pinch)
        imageView.isUserInteractionEnabled = true
    }

    @objc private func handlePinch(_: UIPinchGestureRecognizer) {
        if gestureRecognizer.state == .began
            || gestureRecognizer.state == .changed {

            let newScale = currentScale * gestureRecognizer.scale
            imageView.transform = CGAffineTransform(
                scaleX: min(max(newScale, minScale), maxScale),
                y: min(max(newScale, minScale), maxScale)
            )
        }
        if gestureRecognizer.state == .ended {
            currentScale = min(max(
                currentScale * gestureRecognizer.scale,
                minScale
            ), maxScale)
            gestureRecognizer.scale = 1.0
        }
    }
}

Logik: in .began/.changed wird die Skalierung über CGAffineTransform mit Clamp angewendet. In .ended wird die Skalierung auf 1,0 zurückgesetzt und der akkumulierte Wert in currentScale gespeichert. Dies verhindert ein Abdriften der Skalierung bei wiederholten Gesten — jeder neue Gestus beginnt vom aktuellen Zustand. Für Bilder wird UIScrollView mit minimumZoomScale/maximumZoomScale anstelle von CGAffineTransform empfohlen.

Beispiel 2: Pinch-to-Zoom unter Android (Kotlin)

Implementiert die ImageView-Skalierung über ScaleGestureDetector mit Matrix. Zeigt die korrekte Handhabung des Pivot-Punkts und die Skalierungsbegrenzung.

kotlin
import android.content.Context
import android.graphics.Matrix
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.widget.ImageView

class PinchZoomImageView(context: Context) : ImageView(context) {

    private val matrix = Matrix()
    private var currentScale = 1f
    private val minScale = 0.5f
    private val maxScale = 3.0f

    private val scaleDetector =
        ScaleGestureDetector(context, ScaleListener())

    private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScale(detector: ScaleGestureDetector): Boolean {
            currentScale = (currentScale * detector.scaleFactor)
                .coerceIn(minScale, maxScale)
            matrix.postScale(
                currentScale,
                currentScale,
                detector.focusX,
                detector.focusY
            )
            imageMatrix = matrix
            return true
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        scaleDetector.onTouchEvent(event)
        return true
    }
}

Die benutzerdefinierte ImageView überschreibt onTouchEvent und übergibt Ereignisse an ScaleGestureDetector. OnScaleListener.onScale() wird bei jeder Fingerbewegung aufgerufen. detector.scaleFactor ist das Delta (1,01 bei langsamem Spreizen). currentScale akkumuliert mit coerceIn zum Clampen. focusX/focusY — der Mittelpunkt zwischen den Fingern, der an postScale für korrekte Pivot-Skalierung übergeben wird.

Beispiel 3: UIScrollView mit Zoom-Unterstützung (iOS)

UIScrollView verfügt über integrierte Pinch-to-Zoom-Unterstützung über seinen Delegaten. Dies ist der bevorzugte Ansatz für Bilder und Dokumente — ScrollView verwaltet Skalierung, Trägheit und Scrollen automatisch.

swift
class ScrollableImageViewController: UIViewController,
                                    UIScrollViewDelegate {

    @IBOutlet private var scrollView: UIScrollView!
    @IBOutlet private var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.minimumZoomScale = 0.5
        scrollView.maximumZoomScale = 3.0
        scrollView.delegate = self
    }

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return imageView
    }
}

UIScrollView erstellt automatisch einen UIPinchGestureRecognizer, verwaltet die Skalierung über die CALayer-Transformation und fügt einen Bounce-Effekt bei Überschreitung der Grenzen hinzu. Der Code reduziert sich auf das Setzen von min/maxZoomScale und die Rückgabe von viewForZooming. Bei IT Sectr verwenden wir UIScrollView für alle Vollbildbilder — dies reduziert das Codevolumen um das Fünffache im Vergleich zur manuellen Implementierung über UIPinchGestureRecognizer.

Häufig gestellte Fragen

Wie unterscheidet sich der Pinch vom Zwickgestus auf dem Trackpad?

Auf einem Touchscreen verwendet Pinch zwei Finger mit Abstandsverfolgung zwischen ihnen. Auf einem MacBook-Trackpad wird der Zoom über UIPinchGestureRecognizer mit denselben Zuständen (.began → .changed → .ended) implementiert, aber die Berührungsquelle ist ein Trackpad mit Force Touch, kein kapazitiver Bildschirm. Die API ist dieselbe, die Mechanik ist identisch.

Wie begrenzt man den minimalen und maximalen Zoom?

In iOS: Nach Erhalt der Skalierung von UIPinchGestureRecognizer mit currentScale multiplizieren und clamp(min: 0.5, max: 3.0) anwenden. In Android: coerceIn(minScale, maxScale) vor matrix.postScale() verwenden. In UIScrollView — über die Eigenschaften minimumZoomScale und maximumZoomScale. Ohne Begrenzung kann der Maßstab ins Unendliche oder auf Null gehen.

Funktioniert Pinch-to-Zoom mit einem Finger?

Nein, der Pinch erfordert mindestens zwei Finger. Für den Ein-Finger-Zoom (Doppeltippen + nach oben/unten ziehen) ist eine benutzerdefinierte Implementierung über UIPanGestureRecognizer oder GestureDetector.onScroll erforderlich. Dies ist ein anderer Gestus mit einer anderen Logik — normalerweise für den Zoom in der Kamera oder auf Karten verwendet.

Zusammenfassung

  • Pinch-to-Zoom ist ein Zwei-Finger-Multi-Touch-Gestus zum Skalieren von Inhalten, der Standard für Bilder, Karten und Dokumente.
  • UIPinchGestureRecognizer in iOS ist ein kontinuierlicher Erkennungselement mit scale (Delta) und velocity (Geschwindigkeit).
  • ScaleGestureDetector in Android ist ein spezialisierter Detektor mit onScale(), focusX/focusY für den Pivot-Punkt.
  • Für UIScrollView ist der Zoom über minimumZoomScale/maximumZoomScale integriert — einfacher als manuelle Implementierung.
  • Begrenzen Sie die Skalierung immer (0,5–3,0) über Clamp — ohne dies kann der Inhalt unsichtbar werden.
  • Der Skalierungs-Pivot-Punkt ist die Mitte zwischen den Fingern; ohne ihn verschiebt sich der Inhalt beim Zoomen.
  • Bei IT Sectr verwenden wir UIScrollView für Bilder und benutzerdefiniertes ScaleGestureDetector für Editoren — die Wahl hängt von der Komplexität der Transformationen ab.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch