Pinch-to-Zoom — mohiyati, mobil ilovalarda chimdilash harakatini qayta ishlash

Muallif: IT Sectr Nashr etilgan: 2026-02-27 O'qish vaqti: 8 daq
Pinch-to-Zoom (barmoqlar bilan chimdilash) — ko'p sensorli masshtablash jesti bo'lib, foydalanuvchi ekranda ikki barmog'ini birlashtirib yoki ochib kontentni kichraytiradi yoki kattalashtiradi. Bu jest tasvirlar, xaritalar, veb-sahifalar va hujjatlarni ko'rish uchun de-fakto standartga aylandi. Apple HIG va Google Material Design ma'lumotlariga ko'ra, Pinch-to-Zoom — vizual kontent bilan ishlaydigan barcha ilovalarda foydalanuvchilar kutadigan asosiy jestdir.

Asosiy fikrlar

  • Pinch-to-Zoom — mobil qurilmalarda kontentni masshtablash uchun ikki barmoqli ko'p sensorli jest.
  • iOS da ishlov berish .began → .changed → .ended uzluksiz kuzatish bilan UIPinchGestureRecognizer orqali amalga oshiriladi.
  • Android da Matrix orqali masshtabni yangilash uchun onScale callback bilan ScaleGestureDetector (Support Library dan) ishlatiladi.
  • UIPinchGestureRecognizer scale (oldingi holatga nisbatan koeffitsient) va velocity (tezlik) xususiyatlariga ega.
  • Zoomni cheklash uchun scale koeffitsientining clamp berilgan min/max qiymatlari (odatda 0.5–3.0) orasida qo'llaniladi.

Pinch-to-Zoom nima?

Pinch-to-Zoom (chimdilash yoki siqish) — ko'rsatilgan kontent masshtabini o'zgartirish uchun ikki barmoqdai foydalanadigan ko'p sensorli jest. Barmoqlarni birlashtirganda (pinch close) masshtab kichrayadi, ochganda (pinch open) — kattalashadi. Jest uzluksiz: sistema barmoqlar orasidagi masofani real vaqtda kuzatib boradi va oraliq hodisalar yaratadi, bu ilovaga masshtabni silliq yangilash imkonini beradi.

Jest mexanikasi ikki teginish nuqtasi orasidagi masofani hisoblashga asoslanadi. iOS va Android Evklid masofasidan foydalanadi: sqrt((x2-x1)² + (y2-y1)²). Joriy scale joriy masofaning boshlang'ich masofaga nisbati sifatida hisoblanadi. Agar boshlang'ich masofa 100px bo'lib, 150px ga aylansa — scale = 1.5 (50% ga oshish). iOS scale ni oldingi holatga nisbatan (delta) uzatadi, Android esa ScaleGestureDetector orqali yig'ilgan scale ni uzatadi.

Google Material Design Guidelines ga ko'ra, Pinch-to-Zoom tasvirlar, xaritalar yoki hujjatlarni ko'rsatadigan ilovalar uchun majburiydir. IT Sectr da biz bu jestni UIPinchGestureRecognizer va ScaleGestureDetector bilan vizual kontent bilan ishlaydigan barcha loyihalarda — galereyalardan tortib tasvir muharrirlarigacha qo'llaymiz.

iOS da Pinch-to-Zoom: UIPinchGestureRecognizer

UIPinchGestureRecognizer — chimdilash jestini aniqlash uchun UIGestureRecognizer ning uzluksiz pastki sinfi. Diskret aniqlagichlardan (UITapGestureRecognizer) farqli o'laroq, hodisalar ketma-ketligini yaratadi: .began (barmoqlar ekranga tegdi), .changed (barmoqlarning har bir harakati), .ended (barmoqlar uzildi).

Asosiy xususiyatlar: scale (CGFloat) — jest boshidan barmoqlar orasidagi masofaning nisbiy o'zgarishi; velocity (CGFloat) — sekundiga scale o'zgarish tezligi. Boshlang'ich scale = 1.0. Barmoqlarni ochganda scale ortadi (1.0 → 1.5 → 2.0), birlashtirganda — kamayadi (1.0 → 0.8 → 0.5). Velocity xususiyati inertsiya uchun ishlatiladi: .ended dan keyin masshtablashni so'nish bilan davom ettirish animatsiyasi mumkin.

UIPinchGestureRecognizer boshqa aniqlagichlar bilan (masalan, xaritada pan + pinch) bir vaqtda ishlash uchun delegate xususiyatini qo'llab-quvvatlaydi. gestureRecognizer(_:shouldRecognizeSimultaneouslyWith()) metodi true qaytaradi va ikkala jest parallel ishlaydi. Apple UIPinchGestureRecognizer ni alohida elementlarga emas, konteyner view ga qo'shishni tavsiya qiladi — bu masshtablashning pivot nuqtasini hisoblashni soddalashtiradi.

Android da Pinch-to-Zoom: ScaleGestureDetector

ScaleGestureDetector — ko'p sensorli masshtablashni aniqlash uchun Android Support Library (android.view) dan sinf. GestureDetector.onFling dan farqli o'laroq, ScaleGestureDetector ikki barmoqli zoom uchun maxsus mo'ljallangan va avtomatik ravishda focusX, focusY (barmoqlar orasidagi markaz) va scaleFactor (oldingi hodisadan masshtab deltasi) ni hisoblab beradi.

ScaleGestureDetector uch metodli OnScaleGestureListener interfeysi orqali ishlaydi: onScaleBegin(detector) (.began analoqi), onScale(detector) (.changed analoqi, boolean qaytaradi — true agar masshtab qabul qilingan bo'lsa), onScaleEnd(detector) (.ended analoqi). Xususiyatlar: scaleFactor — oldingi hodisaga nisbatan masshtab ko'paytiruvchisi (~1.01 sekin ochishda), focusX/focusY — barmoqlar orasidagi markaz koordinatalari.

View ga masshtabni qo'llash uchun odatda Matrix ishlatiladi: view.imageMatrix.postScale(scaleFactor, scaleFactor, focusX, focusY). Matrix transformatsiyalarning yig'ilishini qo'llab-quvvatlaydi — har bir postScale chaqiruvi mavjud o'zgartirishga yangi o'zgartirish qo'shadi. Muhim: ScaleGestureDetector minimal/maksimal masshtabni cheklamaydi — bu dasturchining vazifasi. IT Sectr da biz ScaleGestureDetector ni maxsus scale chegaralari (0.5–3.0) va oshib ketishda qaytish animatsiyasi bilan qo'llaymiz.

Zoom cheklovi va pivot nuqtasi

Pinch-to-Zoom ni joriy qilishda minimal va maksimal masshtabni cheklash juda muhim — busiz foydalanuvchi tasvirni cheksizgacha kattalashtirishi yoki ko'rinmas darajada kichraytirishi mumkin. Standart qiymatlar: min = 0.5 (asl o'lchamning 50%), max = 3.0 (300%). iOS da cheklash clamp orqali amalga oshiriladi: newScale = min(max(currentScale * gesture.scale, minScale), maxScale). Android da — postScale dan keyin tekshirish orqali.

Pivot nuqtasi — masshtablash amalga oshiriladigan barmoqlar orasidagi markaz. iOS avtomatik ravishda ikki teginishning markazini hisoblab, uni location(in:) orqali uzatadi — dasturchi pivotni qo'lda hisoblashi shart emas. Android ScaleGestureDetector da focusX/focusY ni taqdim etadi, lekin Matrix orqali qo'llashda pivot postScale(scaleFactor, scaleFactor, focusX, focusY) da uchinchi va to'rtinchi argument sifatida uzatiladi. Pivot nuqtasisiz masshtablash yuqori chap burchakka (0,0) nisbatan amalga oshiriladi, bu zoom paytida kontentning siljishiga olib keladi.

IT Sectr tajribasiga ko'ra, pivot nuqtasini to'g'ri hisoblash — Pinch-to-Zoom ni joriy qilishda eng ko'p uchraydigan xato manbai. 90% hollarda GestureRecognizer va ScaleGestureDetector ning ichki koordinatalaridan foydalanish kifoya, pivotni qo'lda hisoblamasdan. Agar kontent masshtablash paytida siljisa — focusX/focusY ni matrix.postScale() ga uzatayotganingizni tekshiring.

Zoomdan keyin inertsiya

Silliq UX uchun jest tugagandan so'ng inertsiya qo'shilishi mumkin: iOS da — UIPinchGestureRecognizer dan velocity ni spring parametrlari bilan UIView.animate uchun ishlating; Android da — OverScroller yoki ValueAnimator. Inertsiya min/max scale chegaralaridan chiqmasligi kerak — yakuniy qiymat oshib ketishda spring qaytish animatsiyasi bilan kesiladi.

Swift va Kotlin da kod misollari

Misol 1: iOS da Pinch-to-Zoom (Swift)

UIImageView ga masshtab chegarasi 0.5 dan 3.0 gacha bo'lgan UIPinchGestureRecognizer qo'shadi. Yig'ilgan masshtabni saqlash bilan minimal joriy qilishni ko'rsatadi.

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
        }
    }
}

Mantiq: .began/.changed da masshtab CGAffineTransform orqali clamp bilan qo'llaniladi. .ended da scale 1.0 ga qaytariladi va yig'ilgan qiymat currentScale da saqlanadi. Bu ko'p jestlar paytida masshtabning "siljishi" ning oldini oladi — har bir yangi jest joriy holatdan boshlanadi. Tasvirlar uchun CGAffineTransform o'rniga minimumZoomScale/maximumZoomScale bilan UIScrollView tavsiya etiladi.

Misol 2: Android da Pinch-to-Zoom (Kotlin)

Matrix bilan ScaleGestureDetector orqali ImageView ni masshtablashni joriy qiladi. Pivot nuqtasini to'g'ri qayta ishlashni va masshtab cheklovini ko'rsatadi.

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
    }
}

Maxsus ImageView onTouchEvent ni bekor qilib, hodisalarni ScaleGestureDetector ga uzatadi. OnScaleListener.onScale() barmoqlarning har bir harakatida chaqiriladi. detector.scaleFactor — delta (sekin ochishda 1.01). currentScale clamp uchun coerceIn bilan yig'iladi. focusX/focusY — barmoqlar orasidagi markaz, to'g'ri pivot masshtablash uchun postScale ga uzatiladi.

Misol 3: Zoom qo'llab-quvvatlovchi UIScrollView (iOS)

UIScrollView delegate orqali o'rnatilgan Pinch-to-Zoom qo'llab-quvvatlashga ega. Bu tasvirlar va hujjatlar uchun afzal qilingan usul — ScrollView masshtabni, inertsiyani va aylantirishni avtomatik boshqaradi.

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 mustaqil ravishda UIPinchGestureRecognizer yaratadi, CALayer transformatsiyasi orqali masshtabni boshqaradi va chegaralarni oshib ketganda bounce effekti qo'shadi. Kod min/maxZoomScale ni o'rnatish va viewForZooming ni qaytarishgacha qisqaradi. IT Sectr da biz barcha to'liq ekran tasvirlari uchun UIScrollView dan foydalanamiz — bu UIPinchGestureRecognizer orqali qo'lda joriy qilish bilan solishtirganda kod hajmini 5 baravar kamaytiradi.

Ko'p beriladigan savollar

Pinch trekpaddagi chimdilashdan qanday farq qiladi?

Sensorli ekranda pinch ular orasidagi masofani kuzatish bilan ikki barmoqdan foydalanadi. MacBook trekpadida masshtablash bir xil holatlar (.began → .changed → .ended) bilan UIPinchGestureRecognizer orqali amalga oshiriladi, ammo teginish manbai sig'imli ekran emas, balki Force Touch bilan trekpad. API bir xil, mexanika bir xil.

Minimal va maksimal zoomni qanday cheklash mumkin?

iOS da: UIPinchGestureRecognizer dan scale olgandan so'ng currentScale ga ko'paytiring va clamp(min: 0.5, max: 3.0) qo'llang. Android da: matrix.postScale() dan oldin coerceIn(minScale, maxScale) orqali. UIScrollView da — minimumZoomScale va maximumZoomScale xususiyatlari orqali. Cheklovsiz masshtab cheksizlikka yoki nolga ketishi mumkin.

Pinch-to-Zoom bir barmoq bilan ishlaydimi?

Yo'q, pinch kamida ikki barmoq talab qiladi. Bir barmoqli zoom (double-tap + yuqoriga/pastga surish) uchun UIPanGestureRecognizer yoki GestureDetector.onScroll orqali maxsus joriy qilish kerak. Bu boshqa mantiqqa ega boshqa jest — odatda kamera yoki xaritalarda zoom uchun ishlatiladi.

Xulosa

  • Pinch-to-Zoom — kontentni masshtablash uchun ikki barmoqli ko'p sensorli jest, tasvirlar, xaritalar va hujjatlar uchun standart.
  • iOS da UIPinchGestureRecognizer — scale (delta) va velocity (tezlik) bilan uzluksiz aniqlagich.
  • Android da ScaleGestureDetector — pivot nuqtasi uchun onScale(), focusX/focusY bilan ixtisoslashgan detektor.
  • UIScrollView uchun zoom minimumZoomScale/maximumZoomScale orqali o'rnatiladi — qo'lda joriy qilishdan soddaroq.
  • Masshtabni clamp orqali majburiy cheklang (0.5–3.0) — busiz kontent ko'rinmas bo'lishi mumkin.
  • Masshtablashning pivot nuqtasi — barmoqlar orasidagi markaz; usiz kontent kattalashganda siljiydi.
  • IT Sectr da tasvirlar uchun UIScrollView, muharrirlar uchun maxsus ScaleGestureDetector dan foydalanamiz — tanlov transformatsiyalar murakkabligiga bog'liq.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing