Tap — основни гест сензорских интерфејса: једнократни додир екрана прстом са накнадним отпуштањем. Tap је примарна радња (primary action) у мобилним оперативним системима — отварање апликација, притискање дугмади, избор елемената листе. Препознаје се за 100–300 ms и генерише догађај клика. На iOS-у се обрађује кроз UITapGestureRecognizer, на Android-у — кроз setOnClickListener или View.onClick.
Главно
Tap (додир, притисак) — гест брзог додиривања екрана прстом или оловком. Гест се састоји од две фазе: додир (touch down) и отпуштање (touch up), које се дешавају на истом месту без померања. Систем препознаје Tap када временски интервал између down и up не прелази граничну вредност (обично 300–500 ms). Ако корисник држи прст дуже — гест се претвара у Long Press.
Tap — основа мобилног UX-а. На свим мобилним платформама Tap замењује леви клик миша који се користи у десктоп интерфејсима. За разлику од клика мишем, Tap нема модификаторе (Shift+клик, Ctrl+клик) ни hover — ово ограничење обликује дизајн мобилних интерфејса. Да би компензовали недостатак прегледа, мобилне платформе користе визуелну повратну спрегу: highlight при додиру, ripple ефекат у Android-у, промену провидности у iOS-у.
Анатомија Tap-а укључује пет фаза на нивоу система: буђење сензора (додир), одређивање координата, филтрација шума (прст не сме да се помери више од граничне удаљености), чекање завршетка (отпуштање или задржавање), класификација (Tap, Long Press, Drag). Модерни сензорски контролери обрађују овај циклус за 8–16 ms при фреквенцији испитивања од 60–120 Hz.
Tap и Click — различити догађаји са различитом физиком. Click — догађај миша који настаје при притискању и отпуштању дугмета миша на истој позицији. Tap — догађај сензорског екрана који настаје при додиру прста. На мобилним уређајима прегледач претвара Tap у догађај click са кашњењем од 300–350 ms (за емулацију двоструког тапа за зум). Ово кашњење је историјски било проблем мобилног веба, док Apple и Google нису увели meta viewport са user-scalable=no.
| Параметар | Tap (сензорски) | Click (миш) |
|---|---|---|
| Улазни уређај | Прст, оловка | Курсор миша |
| Фазе | touchstart → touchend | mousedown → mouseup |
| Преглед (hover) | Нема | Има (hover) |
| Кашњење | 0–500 ms | 0 ms |
| Прецизност | Ниска (прст је шири од курсора) | Висока (пикселска) |
| Модификатори | Нема | Shift, Ctrl, Cmd |
| Вишеструки | Мултитач (2+ прста) | Нема (један курсор) |
Touch Events — је посебан API од Mouse Events. Сензорски догађаји (touchstart, touchmove, touchend) преносе низ тачака додира (TouchList), координате, снагу притиска (pressure) и величину области додира (radiusX, radiusY). Mouse Events преноси само координате курсора. Модерни прегледачи синтетишу click из touchend-а, ако није било покрета прста и догађаја touchcancel. Pointer Events API обједињује оба приступа, пружајући унификовану обраду свих улазних уређаја.
UITapGestureRecognizer — стандардни препознавач појединачног и вишеструког Tap-а у iOS SDK. Подржава конфигурацију numberOfTapsRequired (број узастопних додира) и numberOfTouchesRequired (број прстију који истовремено додирују). Препознавач прелази у стање UIGestureRecognizerStateRecognized када корисник отпусти прст и додир не прелази границу померања.
// UITapGestureRecognizer са подршком за Double Tap
class InteractiveImageViewController: UIViewController {
private var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Single Tap — прикажи/сакриј контроле
let singleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleSingleTap)
)
imageView.addGestureRecognizer(singleTap)
// Double Tap — зумирање слике
let doubleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleDoubleTap)
)
doubleTap.numberOfTapsRequired = 2
// Single Tap се активира само ако Double Tap није препознат
singleTap.require(doubleTap.toFail())
imageView.addGestureRecognizer(doubleTap)
}
@objc private func handleSingleTap() { /* показать контролы */ }
@objc private func handleDoubleTap() { /* зуммировать */ }
}Важан образац: при истовременој подршци за Single и Double Tap потребно је позвати require(_:toFail:). Без овога, single tap ће деловати одмах, не дозвољавајући систему да сачека други додир. iOS такође подржава препознавање Tap-а кроз UIControl.addTarget — за UIButton, UISwitch и друге контроле. Уграђене UIKit контроле већ имају стандардну обраду Tap-а, а додавање UITapGestureRecognizer преко њих може довести до конфликата.
View.setOnClickListener — стандардни Android SDK метод за обраду кликова на View. Када корисник додирне View и отпусти прст на истом елементу (touch down → touch up у оквиру View), позива се метод onClick(). Android аутоматски додаје ripple ефекат (на API 21+) са анимацијом додира. Дугме се сматра притиснутим у стању PRESSED, које се визуелно приказује кроз селектор или RippleDrawable.
// setOnClickListener у Fragment-у са Data Binding-ом
class ItemListFragment : Fragment() {
private var binding: FragmentItemListBinding? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentItemListBinding.bind(view)
binding.submitButton.setOnClickListener {
submitForm()
}
// Слушалац са debounce-ом за спречавање двоструког клика
binding.submitButton.setOnClickListener(
DebouncingClickListener {
submitForm()
}
)
}
private fun submitForm() {
// Слање података форме
}
}Debounce — важан образац у Android програмирању. Корисник може случајно да притисне дугме два пута у кратком временском интервалу, што доводи до двоструког слања форме или двоструког извршења радње. Решење: омотач DebouncingClickListener који блокира поновљене кликове у трајању од 500–1000 ms. Google препоручује коришћење овог приступа у званичним примерима Android Architecture Components. За RecyclerView је обезбеђен setOnItemClickListener кроз ListAdapter са callback интерфејсом.
Double Tap (двоструки додир) — два узастопна Tap-а са интервалом не већим од 300–400 ms. Користи се за зумирање слика (мапе, фотографије), лајкове на друштвеним мрежама (Instagram, Twitter), повратак на почетак листе (Phone, Messages). Triple Tap (троструки додир) ређе се среће — углавном се користи за accessibility функције (режим преко целог екрана, VoiceOver) и у играма.
Имплементација Double Tap-а захтева синхронизацију са Single Tap-ом: ако додате оба геста на један елемент, Single Tap ће радити са кашњењем (систем чека други додир). У iOS-у ово кашњење се контролише кроз require(toFail:) — Single Tap се одлаже док систем није сигуран да Double Tap неће уследити. У Android-у се користи GestureDetector.OnDoubleTapListener са callback-овима onSingleTapConfirmed и onDoubleTap. onSingleTapConfirmed се позива тек након тајмаута, када је систем сигуран да је у питању појединачни додир.
// Double Tap у Android-у кроз GestureDetector
class PhotoViewerActivity : AppCompatActivity() {
private var gestureDetector: GestureDetector? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
toggleControls() // прикажи/сакриј контроле
return true
}
override fun onDoubleTap(e: MotionEvent): Boolean {
zoomToPoint(e.x, e.y) // зум у тачки додира
return true
}
})
}
}Instagram-like double tap — популаран UX образац за друштвене апликације. Двоструки додир на фотографију покреће анимацију лајка (икона срца). Имплементира се кроз GestureDetector у Android-у или UITapGestureRecognizer са numberOfTapsRequired=2 у iOS-у. За анимацију се користе Core Animation на iOS-у и ObjectAnimator/AnimatorSet на Android-у. Време одзива double tap-а мора бити минимално — корисник очекује тренутну анимацију након другог додира.
Human Interface Guidelines Apple-а и Material Design Google-а постављају конкретне захтеве за Tap. Минимална величина touch-target-а: 44×44 pt за iOS и 48×48 dp за Android. То одговара ~9 mm на екрану — величини јастучића прста просечне одрасле особе. Растојање између touch циљева треба да буде најмање 8 pt/dp да би се спречили лажни додири.
| Правило | Вредност | Образложење |
|---|---|---|
| Минимална величина циља | 44×44 pt (iOS) / 48×48 dp (Android) | Просечна величина јастучића прста ~9 mm |
| Размак између циљева | ≥8 pt / ≥8 dp | Спречавање лажних додира |
| Визуелна повратна спрега | Highlight / Ripple | Потврда регистрације додира |
| Трајање анимације додира | 100–200 ms | Довољно за перцепцију, не успорава интерфејс |
| Обрада Double Tap-а | Захтева кашњење Single Tap-а | Спречавање лажног активирања |
| Ивичне области екрана | Повећана зона погађања | Компензација држања уређаја |
Визуелна повратна спрега је обавезна за Tap. Корисник мора да види да је додир регистрован: промена боје, opacity, ripple анимација или highlight. Без повратне спреге, корисник може поново да притисне, изазивајући нежељене радње. У iOS-у стандардна touch highlight анимација — промена провидности на 0.3 са трајањем од 0.15 s. У Android-у — Material ripple ефекат који се шири од тачке додира. Немојте користити кашњење пре визуелне повратне спреге — корисник треба да види реакцију истовремено са додиром.
Често постављана питања
Tap — сензорски догађај, Click — догађај миша. У прегледачу, Tap се претвара у Click са кашњењем од 300 ms (за разликовање од Double Tap Zoom-а). Модерни прегледачи (Chrome 32+, Safari 9.1+) искључују ово кашњење при meta viewport са width=device-width. Користите Pointer Events API за унификовану обраду: pointerdown/pointerup одговарају свим улазним уређајима (миш, додир, оловка).
Минимални touch target — 44×44 тачке (iOS) или 48×48 dp (Android). То одговара приближно 9×9 mm на физичком екрану. Ако је дугме визуелно мање (нпр. икона 24×24), повећајте hit area кроз UIEdgeInsets (iOS) или TouchDelegate (Android). Размак између суседних циљева треба да буде најмање 8 јединица да би се избегли лажни додири.
Double-click prevention се имплементира кроз debounce механизам: након првог клика, дугме се блокира на 500–1000 ms. У Android-у користите DebouncingClickListener (готово решење из Architecture Components). У iOS-у — искључите isEnabled дугмета одмах након притиска и укључите га кроз DispatchQueue.main.asyncAfter. У веб апликацијама — поставите disabled флаг на button елементу након првог клика.
Long Tap (Long Press) — задржавање прста на екрану 500+ ms без померања. Tap — брзи додир (100–300 ms). Tap извршава главну радњу (Primary Action), Long Tap — секундарну (контекстни мени, уређивање). У iOS-у Tap обрађује UITapGestureRecognizer, Long Press — UILongPressGestureRecognizer. У Android-у — setOnClickListener vs setOnLongClickListener.
Да, оловке се обрађују као Tap кроз стандардни сензорски API. Apple Pencil преноси force (снага притиска), altitudeAngle (угао нагиба) и azimuth (азимут). S Pen у Android-у преноси сличне параметре кроз MotionEvent.getPressure() и getAxisValue(MotionEvent.AXIS_TILT). За оловке се touch target може смањити на 24×24 тачке, јер је прецизност оловке већа од прста.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође