Swipe:什么是滑动,移动开发中的滑动处理

作者: IT Sectr 发布日期: 2026-02-27 阅读时间: 8 分钟
Swipe(滑动)——一种离散手势,用户用手指在屏幕上朝一个方向滑动——向右、向左、向上或向下。与拖拽(drag)不同,滑动不追踪连续运动:当手指越过最小阈值并离开屏幕时,它被识别为已完成的操作。根据 Nielsen Norman Group(2024)的 UX 研究,滑动是移动应用中仅次于点击的第二频繁手势,用于 23% 的用户交互。

要点

  • Swipe — 离散手势:在越过阈值并抬起手指后,被识别为一个已完成的操作。
  • 在 iOS 中,滑动处理通过 UISwipeGestureRecognizer 进行,可配置方向(direction)和手指数量。
  • 在 Android 中,使用 GestureDetector 配合 onFling(MotionEvent) 或 OnSwipeTouchListener 以简化 API。
  • 滑动阈值——iOS 中约 20px(viewConfiguration),在 Android 中通过 VelocityTracker 配置。
  • 对于列表(UITableView/RecyclerView),使用内置机制——UISwipeActionsConfiguration 和 ItemTouchHelper——代替手动识别。

什么是滑动?

滑动——手指在屏幕表面快速滑动的动作,以抬起手指结束。滑动可以是短促的(滚动元素)或长距离的(打开帘幕),但关键特征是离散性:系统将其识别为单个事件,而不是连续的坐标序列。

移动操作系统根据三个参数定义滑动:最小距离(阈值)、最小速度(velocity)和方向。如果手指移动缓慢或距离不足,系统将手势解释为平移(pan)或点击。阈值因平台而异:iOS 使用 UISwipeGestureRecognizer 常量固定阈值,Android 使用 ViewConfiguration.getScaledTouchSlop(),根据屏幕密度返回约 8–16 dp。

根据 Android Developers Documentation,GestureDetector 中的 onFling(滑动)在速度超过 100 px/s 且距离超过 50px 时触发。在 IT Sectr,我们将滑动用于导航(图库、卡片界面、引导)——这种手势对所有年龄段的用户都直观易懂。

滑动 vs 平移:有什么区别?

滑动和平移(pan/drag)——不同类型的手势,尽管两者都使用手指在屏幕上的移动。滑动是离散的,意思是„执行一个操作”,而平移是连续的,意思是„只要手指在屏幕上就移动对象”。

参数 滑动(Swipe) 平移(Pan/Drag)
类型 离散 连续
事件 一个(识别/未识别) 多个(.began → .changed → .ended)
速度 高(快速移动) 任意(慢速移动)
iOS 示例 UISwipeGestureRecognizer UIPanGestureRecognizer
Android 示例 GestureDetector.onFling() GestureDetector.onScroll()
场景 删除邮件、翻页 移动地图、拖拽文件
坐标追踪 否(仅方向) 是(持续更新坐标)

在滑动和平移之间的选择取决于任务。对于元素的操作(删除、归档、打开菜单),使用滑动。对于直接操作(移动、缩放)——使用平移。在同一元素上混合手势需要 require(toFail:) 或自定义逻辑。

iOS 中的滑动:UISwipeGestureRecognizer

UISwipeGestureRecognizer——UIGestureRecognizer 的子类,识别四个方向之一的离散滑动。与 UIPanGestureRecognizer 不同,它不生成中间 .changed 事件:识别时 action 仅被调用一次。

direction 属性(UISwipeGestureRecognizer.Direction)设置跟踪的方向——.left、.right、.up、.down。可以通过掩码组合:水平滑动使用 [.left, .right]。numberOfTouchesRequired 属性确定手指数量——默认为 1。UISwipeGestureRecognizer 没有可配置的距离阈值——iOS 使用约 20px 的内置值,足以进行可靠识别。

由于 UISwipeGestureRecogniser 是离散识别器,它与 UIPanGestureRecognizer 不冲突:慢速移动时触发 pan,快速移动时触发 swipe。但是当与 UITapGestureRecognizer 共存于同一视图时,可能需要 require(toFail:) 以防止误识别点击。

Android 中的滑动:GestureDetector

在 Android 中,识别滑动的主要 API 是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 是一种简化 API 的常见模式:开发者无需手动计算方向和速度。Android Support Library 不包含内置的„SwipeDetector”,因此自定义包装器是标准解决方案。

对于列表中的滑动,Google 建议使用 RecyclerView 中的 ItemTouchHelper.SimpleCallback,它抽象了手势检测、动画和 onSwiped() 回调。在 IT Sectr,我们为 ViewPager2 和卡片界面使用自定义 SwipeListener——这提供了对滑动灵敏度的控制,同时不影响性能。

列表中的滑动:SwipeActions 和 ItemTouchHelper

对于列表(UITableView、RecyclerView),Apple 和 Google 提供专门的 API,替代手动添加 UISwipeGestureRecognizer。这些 API 支持操作按钮、自定义动画和„滑动删除”手势——移动应用的标准模式。

在 iOS(11+)中使用 UISwipeActionsConfiguration:tableView(_:leadingSwipeActionsConfigurationForRowAt:) 方法返回 UIContextualAction 数组——带有标题、样式(destructive、normal)和处理程序的按钮。例如,„删除”——红色背景的 .destructive,„归档”——灰色的 .normal。系统自动为按钮的出现添加动画,并在按下后调用 completion 块。

在 Android 中,ItemTouchHelper.SimpleCallback 通过 ItemTouchHelper.attachToRecyclerView() 附加到 RecyclerView。参数——方向标志(start、end、up、down)和回调 onSwiped(viewHolder, direction)。在 onSwiped 内部调用 adapter.notifyItemRemoved(position) 以动画方式删除元素。ItemTouchHelper 自动处理手势、与滚动的冲突以及滑动未完成时元素的恢复。根据 Google I/O 2024 的数据,ItemTouchHelper 被 70% 的具有列表滑动操作的 Android 应用使用。

Swift 和 Kotlin 代码示例

示例 1:iOS 中向左滑动(Swift)

将 UISwipeGestureRecognizer 添加到视图以返回上一个屏幕。代码展示了使用 .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)
        }
    }
}

识别器绑定到控制器的根视图。navigationController.viewControllers.count 的检查确保 pop 仅在堆栈中存在上一个屏幕时执行。对于模态控制器使用 dismiss。代码不需要状态检查——UISwipeGestureRecognizer 是离散的,仅在成功识别时调用 action。

示例 2:Android 中的滑动(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:iOS 中的 SwipeActions(UITableView)

在向左滑动表格单元格时添加删除按钮。使用 iOS 11+ 的内置 API,无需手动手势识别。

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,我们将此 API 用于所有带操作的列表——它是标准化的,支持 VoiceOver,且不需要自定义 GestureRecognizer。

常见问题

如何区分滑动和平移?

滑动是离散手势,快速移动并抬起手指;平移是连续拖拽,追踪坐标。UISwipeGestureRecognizer 触发一次,UIPanGestureRecognizer 生成 .began → .changed → .ended。选择取决于场景:滑动用于操作(删除、翻页),平移用于移动(地图、滑块)。

滑动在 iOS 和 Android 上的工作方式相同吗?

手势逻辑相同,但 API 不同。iOS 使用UISwipeGestureRecognizer 配合 direction。Android 使用 GestureDetector.onFling() 配合自定义阈值。结果——不同实现下的相同用户体验。跨平台框架(Flutter、React Native)通过统一的滑动 API 抽象了差异。

如何处理列表中的滑动?

在 iOS(11+)中,请在 UITableViewDelegate 中使用UISwipeActionsConfiguration。在 Android 中——为 RecyclerView 使用ItemTouchHelper.SimpleCallback。这些 API 替代了手动 GestureRecognizer,支持操作按钮和动画,正确处理与滚动的冲突,并适应平台 HIG。

总结

  • 滑动——手指快速滑动的离散手势,频率仅次于点击(23% 的交互)。
  • 在 iOS 中,UISwipeGestureRecogniser 在四个方向上以约 20px 的固定阈值处理滑动。
  • 在 Android 中,GestureDetector.onFling() 使用自定义的速度和距离阈值。
  • 对于列表,请使用 UISwipeActionsConfiguration(iOS)和 ItemTouchHelper(Android)代替手动识别器。
  • 滑动不同于平移,具有离散性和高速性——设计时请不要混淆这些手势。
  • Android 中的自定义 OnSwipeTouchListener 通过隐藏方向计算简化了 GestureDetector API。
  • 在 IT Sectr,我们将滑动应用于导航、元素删除和引导流程——这种手势直观且无需学习。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读