Свипе: шта је то, обрада превлачења у мобилном развоју

Аутор: IT Sectr Објављено: 2026-02-27 Време читања: 8 мин
Свипе (превлачење) — дискретни гест, при чему корисник превлачи прстом по екрану у једном правцу — десно, лево, горе или доле. За разлику од превлачења (drag), свипе не прати непрекидно кретање: препознаје се као завршена радња након што прст пређе минимални праг и одвоји се од екрана. Према UX истраживању Nielsen Norman Group (2024), свипе — други по учесталости гест у мобилним апликацијама после тапа, коришћен у 23% интеракција корисника.

Главно

  • Свипе — дискретни гест: препознаје се као једна завршена радња након преласка прага и одвајања прста.
  • У иОС-у обрада превлачења се врши кроз UISwipeGestureRecognizer са подешавањем правца (direction) и броја прстију.
  • У Андроиду се користи GestureDetector са onFling(MotionEvent) или OnSwipeTouchListener за поједностављени АПИ.
  • Праг превлачења — ~20px на иОС-у (viewConfiguration) и подешава се кроз VelocityTracker у Андроиду.
  • За листе (UITableView/RecyclerView) користе се уграђени механизми — UISwipeActionsConfiguration и ItemTouchHelper — уместо ручног препознавања.

Шта је свипе?

Свипе — брзо клизање прста по површини екрана које се завршава одвајањем. Свипе може бити кратак (листање елемента) или дуг (отварање завесе), али кључна карактеристика — дискретност: систем га препознаје као један догађај, а не као непрекидни низ координата.

Мобилни ОС одређују свипе по три параметра: минимално растојање (праг), минимална брзина (velocity) и правац. Ако се прст креће споро или растојање није довољно, систем тумачи гест као панорамирање (pan) или тап. Вредности прага се разликују између платформи: иОС користи константу UISwipeGestureRecognizer са фиксним прагом, Андроид — ViewConfiguration.getScaledTouchSlop(), који враћа ~8–16 dp у зависности од густине екрана.

Према Android Developers Documentation, onFling (свипе) у GestureDetector-у се активира при брзини изнад 100 px/s и растојању од 50px. У IT Sectr-у користимо свипе за навигацију (галерије, картични интерфејси, онбординг) — овај гест је интуитивно разумљив корисницима свих узраста.

Свипе vs панорамирање: у чему је разлика?

Свипе и панорамирање (pan/drag) — различити типови гестова, иако оба користе покрет прста по екрану. Свипе је дискретан и значи „уради једну радњу”, док је панорамирање непрекидно и значи „померај објекат док је прст на екрану”.

Параметар Свипе Панорамирање (Pan/Drag)
Тип Дискретан Непрекидан
Догађаји Један (препознат/није препознат) Више (.began → .changed → .ended)
Брзина Висока (брз покрет) Било која (споро кретање)
Пример иОС UISwipeGestureRecognizer UIPanGestureRecognizer
Пример Андроид GestureDetector.onFling() GestureDetector.onScroll()
Сценарио Обрисати имејл, прелистати страницу Померити мапу, превући датотеку
Праћење координата Не (само правац) Да (континуирано ажурирање координата)

Избор између свипе-а и панорамирања зависи од задатка. За радње са елементом (брисање, архивирање, отварање менија) користите свипе. За директно манипулисање (померање, скалирање) — панорамирање. Мешање гестова на истом елементу захтева require(toFail:) или прилагођену логику.

Свипе у иОС-у: UISwipeGestureRecognizer

UISwipeGestureRecognizer — подкласа UIGestureRecognizer-а која препознаје дискретни свипе у једном од четири правца. За разлику од UIPanGestureRecognizer-а, не генерише међу-догађаје .changed: при препознавању action се позива тачно једном.

Својство direction (UISwipeGestureRecognizer.Direction) поставља правац праћења — .left, .right, .up, .down. Може се комбиновати кроз маску: [.left, .right] за хоризонтална превлачења. Својство numberOfTouchesRequired одређује број прстију — подразумевано 1. UISwipeGestureRecognizer нема подесиви праг растојања — иОС користи уграђену вредност од око 20px, довољну за поуздано препознавање.

Пошто је UISwipeGestureRecogniser дискретни препознавач, не конфликтује са UIPanGestureRecognizer-ом: при спором покрету активираће се pan, при брзом — swipe. Међутим, при заједничком постојању са UITapGestureRecognizer-ом на истом view-у може бити потребно require(toFail:) ради спречавања лажног препознавања тапа.

Свипе у Андроиду: GestureDetector

У Андроиду главни АПИ за препознавање свипе-а је GestureDetector са колбеком OnGestureListener, наиме метод onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY). GestureDetector анализира почетни и крајњи положај прста, брзину кретања по осама и растојање, након чега позива onFling при прекорачењу прагова.

Минимални прагови се подешавају кроз ViewConfiguration: VelocityTracker.getMinVelocity() (~100 px/s) и ViewConfiguration.getScaledTouchSlop() (~8–16 dp). Прилагођени OnSwipeTouchListener — распрострањени образац који поједностављује АПИ: програмер не мора ручно да израчунава правац и брзину. Android Support Library не садржи уграђени „SwipeDetector”, па је прилагођени омотач стандардно решење.

За свипе у листама Google препоручује коришћење ItemTouchHelper.SimpleCallback из RecyclerView-а, који апстрахује детекцију геста, анимацију и колбекове onSwiped(). У IT Sectr-у користимо прилагођени SwipeListener за ViewPager2 и картичне интерфејсе — то даје контролу над осетљивошћу свипе-а без утицаја на перформансе.

Свипе у листама: SwipeActions и ItemTouchHelper

За листе (UITableView, RecyclerView) Apple и Google пружају специјализоване АПИ-је који замењују ручно додавање UISwipeGestureRecognizer-а. Ови АПИ-ји подржавају дугмад за радње, прилагођену анимацију и гестове „превуци да обришеш” — стандардне обрасце мобилних апликација.

У иОС-у (11+) користи се UISwipeActionsConfiguration: метод tableView(_:leadingSwipeActionsConfigurationForRowAt:) враћа низ UIContextualAction — дугмади са насловом, стилом (destructive, normal) и руковаоцем. На пример, „Обриши” — .destructive са црвеном позадином, „Архива” — .normal са сивом. Систем сама анимира појаву дугмади и позива completion блок након притиска.

У Андроиду ItemTouchHelper.SimpleCallback се прикачи на RecyclerView кроз ItemTouchHelper.attachToRecyclerView(). Параметри — заставице праваца (start, end, up, down) и колбек onSwiped(viewHolder, direction). Унутар onSwiped позива се adapter.notifyItemRemoved(position) за брисање елемента са анимацијом. ItemTouchHelper аутоматски обрађује гестове, конфликте са скроловањем и враћање елемента ако свипе није завршен. Према Google I/O 2024, ItemTouchHelper се користи у 70% Андроид апликација са свипе радњама у листама.

Примери кода у Swift и Kotlin

Пример 1: Превлачење улево на иОС-у (Swift)

Додаје UISwipeGestureRecognizer на view за повратак на претходни екран. Код показује минималну конфигурацију препознавача са правцем .left.

swift
import UIKit

class CardViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let swipeLeft = UISwipeGestureRecognizer(
            target: self,
            action: #selector(handleSwipeLeft(_:))
        )
        swipeLeft.direction = .left
        swipeLeft.numberOfTouchesRequired = 1
        view.addGestureRecognizer(swipeLeft)
    }

    @objc private func handleSwipeLeft(_: UISwipeGestureRecognizer) {
        guard let nav = navigationController else { return }
        if nav.viewControllers.count > 1 {
            nav.popViewController(animated: true)
        } else {
            nav.dismiss(animated: true)
        }
    }
}

Препознавач се везује за root-view контролера. Провера navigationController.viewControllers.count гарантује да се pop извршава само када постоји претходни екран у стеку. За модалне контролере користи се dismiss. Код не захтева проверу state — UISwipeGestureRecognizer је дискретан и позива action само при успешном препознавању.

Пример 2: Превлачење у Андроиду (Kotlin) са прилагођеним OnSwipeTouchListener

Имплементира једноставан омотач GestureDetector-а који одређује правац превлачења и позива колбекове onSwipeLeft/Right.

kotlin
import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View

open class OnSwipeTouchListener(context: Context) : View.OnTouchListener {

    private val gestureDetector = GestureDetector(context, GestureListener())

    override fun onTouch(v: View, event: MotionEvent): Boolean {
        return gestureDetector.onTouchEvent(event)
    }

    private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {

        companion object {
            private const val SWIPE_THRESHOLD = 100
            private const val SWIPE_VELOCITY_THRESHOLD = 100
        }

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            val diffX = e2.x - e1!!.x
            val diffY = e2.y - e1.y

            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD
                    && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
                ) {
                    if (diffX > 0) onSwipeRight()
                    else onSwipeLeft()
                    return true
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD
                    && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD
                ) {
                    if (diffY > 0) onSwipeDown()
                    else onSwipeUp()
                    return true
                }
            }
            return false
        }
    }

    open fun onSwipeLeft() {}
    open fun onSwipeRight() {}
    open fun onSwipeUp() {}
    open fun onSwipeDown() {}
}

OnSwipeTouchListener проширује SimpleOnGestureListener, имплементирајући onFling. diffX/diffY одређују правац, SWIPE_THRESHOLD (100px) и SWIPE_VELOCITY_THRESHOLD (100 px/s) — прагови. Коришћење: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).

Пример 3: SwipeActions у иОС-у (UITableView)

Додаје дугме за брисање при превлачењу улево по ћелији табеле. Користи уграђени АПИ иОС 11+ без ручног препознавања гестова.

swift
func tableView(
    _ tableView: UITableView,
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(
        style: .destructive,
        title: "Обриши"
    ) { _, _, completionHandler in
        items.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .automatic)
        completionHandler(true)
    }
    deleteAction.backgroundColor = .systemRed

    let config = UISwipeActionsConfiguration(actions: [deleteAction])
    config.performsFirstActionWithFullSwipe = true
    return config
}

Метод враћа UISwipeActionsConfiguration са низом UIContextualAction. style: .destructive аутоматски поставља црвену позадину. performsFirstActionWithFullSwipe = true омогућава извршење радње потпуним превлачењем без додатног притиска. У IT Sectr-у користимо овај АПИ за све листе са радњама — стандардизован је, подржава VoiceOver и не захтева прилагођене GestureRecognizer-е.

Често постављана питања

Како разликовати свипе од панорамирања?

Свипе — дискретни гест са брзим покретом и одвајањем прста, панорамирање — непрекидно превлачење са праћењем координата. UISwipeGestureRecognizer се активира једном, UIPanGestureRecognizer генерише .began → .changed → .ended. Избор зависи од сценарија: свипе — за радње (обрисати, прелистати), pan — за померање (мапа, клизач).

Да ли свипе ради исто на иОС-у и Андроиду?

Логика геста је идентична, али се АПИ разликује. иОС користи UISwipeGestureRecognizer са direction. Андроид користи GestureDetector.onFling() са прилагођеним праговима. Резултат — исти UX са различитом имплементацијом. Вишеплатформски оквири (Flutter, React Native) апстрахују разлику кроз јединствени АПИ за свипе.

Како обрадити свипе у листи?

У иОС-у (11+) користите UISwipeActionsConfiguration у UITableViewDelegate-у. У Андроиду — ItemTouchHelper.SimpleCallback за RecyclerView. Ови АПИ-ји замењују ручне GestureRecognizer-е, подржавају дугмад за радње и анимацију, исправно обрађују конфликт са скроловањем и прилагођавају се платформским HIG смерницама.

Закључци

  • Свипе — дискретни гест брзог клизања прстом, други по учесталости после тапа (23% интеракција).
  • У иОС-у UISwipeGestureRecogniser обрађује превлачења у четири правца са фиксним прагом ~20px.
  • У Андроиду GestureDetector.onFling() се користи са прилагођеним праговима брзине и растојања.
  • За листе користите UISwipeActionsConfiguration (иОС) и ItemTouchHelper (Андроид) уместо ручних препознавача.
  • Свипе се разликује од панорамирања дискретношћу и високом брзином — не мешајте ове гестове при пројектовању.
  • Прилагођени OnSwipeTouchListener у Андроиду поједностављује АПИ GestureDetector-а, скривајући израчунавање правца.
  • У IT Sectr-у примењујемо свипе за навигацију, брисање елемената и онбординг — гест је интуитиван и не захтева учење.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође