UIContextMenuInteraction深度解析:从UILabel复制到自定义菜单

iOS开发 UILabel长按弹出复制选项-UIContextMenuInteraction UILabel通过UIContextMenuInteraction实现长按弹出复制选项。 阅读详情

UIContextMenuInteraction深度解析:从UILabel复制到自定义菜单

在iOS应用开发中,交互的细腻程度往往决定了用户体验的上限。回想一下,当你长按一段文本,一个简洁的菜单优雅浮现,轻点“复制”,内容便已就绪——这种流畅感,正是现代iOS应用所追求的。UIContextMenuInteraction 正是实现这种“优雅力量”的核心API。它远不止于为UILabel添加一个复制按钮那么简单。对于已经熟悉基础iOS开发的你来说,掌握这个API,意味着能够将应用的交互层级从“可用”提升到“精致”甚至“令人愉悦”。本文将带你深入UIContextMenuInteraction的肌理,从最基础的文本复制场景出发,逐步拆解如何构建高度定制化、功能丰富的上下文菜单,让你的应用在细节处脱颖而出。

1. 理解UIContextMenuInteraction:不止于长按复制

在iOS 13之前,实现长按弹出菜单(如复制、粘贴)通常依赖于UIMenuController,它功能相对基础,定制化能力有限。UIContextMenuInteraction的引入,是苹果在交互范式上的一次重要升级。它不仅仅是一个“菜单”,更是一个完整的交互会话。

核心思想:UIContextMenuInteraction将一次长按交互抽象为一系列可配置的阶段——从按压开始、到菜单预览呈现、再到菜单项选择与执行,最后交互结束。开发者可以在每个阶段注入自定义逻辑,从而创造出远超简单文本复制的复杂交互。

与旧方案的对比,其优势是压倒性的:

特性维度UIMenuController (旧)UIContextMenuInteraction (新)
系统版本iOS 3.0+iOS 13.0+
交互丰富度静态菜单列表支持预览视图、子菜单、菜单内联展开
视觉定制非常有限,系统样式为主高度可定制,包括图标、颜色、状态(禁用/开启)
动画与反馈基础弹出动画完整的交互动画链,支持自定义预览弹出/消失位置
数据传递依赖全局状态(如UIPasteboard)通过UIAction的handler闭包精准传递上下文
适用控件主要为UITextView/UITextField等文本控件任何 UIView 及其子类

提示:如果你的应用需要支持iOS 13以下的版本,可能需要准备两套实现方案。但对于面向现代iOS系统的应用,UIContextMenuInteraction应是首选。

它的工作流程可以概括为以下几个关键步骤,理解这个流程是进行高级定制的基础:

  1. 交互附着:将一个UIContextMenuInteraction实例添加到目标UIView上,并设置其代理(delegate)。
  2. 配置请求:当用户执行交互(如长按)时,系统会调用代理方法,请求菜单配置(UIContextMenuConfiguration)。
  3. 菜单构建:在配置的actionProvider中,返回一个UIMenu对象,其中包含一个或多个UIAction(或嵌套的子菜单)。
  4. 预览定制(可选):通过另外两个代理方法,可以自定义菜单弹出和消失时的预览视图的锚点位置,实现更酷炫的视觉效果。
  5. 动作执行:用户点击某个UIAction,其关联的handler闭包会被执行,完成具体业务逻辑。

2. 基石:为UILabel实现优雅的复制功能

让我们从最常见的场景开始:让一个普通的UILabel支持长按复制其文本内容。这是理解整个API运作的绝佳起点。

首先,你需要为你的视图控制器(或视图)遵循UIContextMenuInteractionDelegate协议,并创建一个交互对象附加到目标标签上。这里有一个关键细节:UILabel的userInteractionEnabled属性默认是NO,你必须将其设为YES,否则交互永远不会被触发。

class DeviceInfoViewController: UIViewController, UIContextMenuInteractionDelegate {
    @IBOutlet weak var deviceNameLabel: UILabel!
    @IBOutlet weak var serialNumberLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupContextMenuForLabel(deviceNameLabel)
        setupContextMenuForLabel(serialNumberLabel)
    }

    private func setupContextMenuForLabel(_ label: UILabel) {
        label.isUserInteractionEnabled = true // 关键一步!
        let interaction = UIContextMenuInteraction(delegate: self)
        label.addInteraction(interaction)
    }
}

接下来是实现核心的代理方法 contextMenuInteraction(_:configurationForMenuAt:)。这个方法要求你返回一个UIContextMenuConfiguration对象,它定义了菜单的内容和行为。

func contextMenuInteraction(_ interaction: UIContextMenuInteraction,
                           configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {

    // 1. 获取触发交互的视图
    guard let targetLabel = interaction.view as? UILabel,
          let labelText = targetLabel.text, !labelText.isEmpty else {
        return nil // 如果文本为空,不显示菜单
    }

    // 2. 创建复制动作
    let copyAction = UIAction(title: "复制",
                              image: UIImage(systemName: "doc.on.doc")) { [weak self] _ in
        UIPasteboard.general.string = labelText
        // 这里可以添加复制成功的反馈,例如一个轻微的震动或提示框
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.success)
    }

    // 3. 创建菜单
    let menu = UIMenu(title: "", children: [copyAction])

    // 4. 创建并返回配置
    return UIContextMenuConfiguration(identifier: nil,
                                      previewProvider: nil) { _ in
        return menu
    }
}

这段代码已经实现了一个功能完整、体验良好的复制功能。但我们可以做得更好。注意到UIContextMenuConfiguration的初始化方法包含一个previewProvider参数吗?它允许你提供一个预览控制器。例如,如果你长按的是一个代表用户名的标签,可以在这里预览该用户的迷你资料卡。

// 假设我们有一个用户模型
let user = User(name: labelText, avatar: someImage)

return UIContextMenuConfiguration(identifier: nil) {
    // 返回一个预览用的视图控制器
    let previewVC = UserPreviewViewController()
    previewVC.user = user
    return previewVC
} actionProvider: { _ in
    return menu
}

3. 进阶:构建功能丰富的自定义菜单

当你的菜单不再满足于单一的“复制”时,UIMenu和UIAction的强大能力就显现出来了。你可以创建包含多种操作、分组、甚至嵌套子菜单的复杂结构。

创建多样化的菜单项:UIAction支持多种状态和样式。

  • 状态:.on, .off, .mixed。这对于表示开关状态的菜单项非常有用(例如,“粗体”、“斜体”)。
  • 属性:.destructive(红色高亮,用于删除等危险操作)、.disabled(禁用状态)。

假设我们正在开发一个笔记应用,长按一段文本标签可以弹出编辑菜单:

func createTextEditMenu(for text: String) -> UIMenu {
    let copyAction = UIAction(title: "复制", image: UIImage(systemName: "doc.on.doc")) { _ in
        UIPasteboard.general.string = text
    }

    let shareAction = UIAction(title: "分享...", image: UIImage(systemName: "square.and.arrow.up")) { _ in
        self.presentShareSheet(for: text)
    }

    let boldAction = UIAction(title: "粗体",
                              image: UIImage(systemName: "bold"),
                              state: isBold ? .on : .off) { _ in
        self.toggleBold()
    }

    let deleteAction = UIAction(title: "删除",
                                image: UIImage(systemName: "trash"),
                                attributes: .destructive) { _ in
        self.deleteText()
    }

    // 将相关操作分组
    let editGroup = UIMenu(title: "", options: .displayInline, children: [boldAction])
    let primaryGroup = UIMenu(title: "", options: .displayInline, children: [copyAction, shareAction])
    let destructiveGroup = UIMenu(title: "", options: .displayInline, children: [deleteAction])

    // 组合所有组成为一个菜单
    return UIMenu(title: "文本操作", children: [primaryGroup, editGroup, destructiveGroup])
}

实现嵌套子菜单:对于功能特别多的场景,子菜单能保持界面整洁。例如,一个“翻译”主菜单项下,可以展开“翻译为英语”、“翻译为日语”等子项。

let translateToEnglish = UIAction(title: "英语") { _ in self.translate(to: .english) }
let translateToJapanese = UIAction(title: "日语") { _ in self.translate(to: .japanese) }

let translateSubmenu = UIMenu(title: "翻译",
                              image: UIImage(systemName: "globe"),
                              children: [translateToEnglish, translateToJapanese])

let mainMenu = UIMenu(children: [copyAction, shareAction, translateSubmenu])

注意:过度嵌套(超过两层)可能会降低操作效率,破坏用户体验。在设计复杂菜单时,务必以用户的操作直觉为先。

4. 深度定制:预览与交互的视觉魔法

UIContextMenuInteraction 最令人惊艳的特性之一,是它对预览(Preview) 的深度支持。这不仅仅是弹出一个菜单,而是构建了一个从触发点到内容预览再到菜单选择的完整视觉叙事。

自定义预览的锚点视图:默认情况下,菜单会从用户长按的视图位置弹出。但通过实现 contextMenuInteraction(_:previewForHighlightingMenuWithConfiguration:) 和 contextMenuInteraction(_:previewForDismissingMenuWithConfiguration:) 方法,你可以控制预览视图从哪个“特定区域”出现和消失。

想象一个聊天应用,长按一条消息气泡。你希望预览和菜单从整个气泡区域弹出,而不仅仅是内部的文本标签。你可以这样做:

func contextMenuInteraction(_ interaction: UIContextMenuInteraction,
                           previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
    // 1. 找到交互发生的视图(可能是消息气泡里的标签)
    guard let label = interaction.view else { return nil }

    // 2. 找到它的父视图——消息气泡容器
    guard let bubbleView = label.superview as? MessageBubbleView else { return nil }

    // 3. 为气泡视图创建预览参数
    let parameters = UIPreviewParameters()
    parameters.backgroundColor = .clear // 让背景透明,只聚焦气泡形状
    parameters.visiblePath = UIBezierPath(roundedRect: bubbleView.bounds, cornerRadius: bubbleView.cornerRadius)

    // 4. 返回一个以气泡视图为目标的预览
    return UITargetedPreview(view: bubbleView, parameters: parameters)
}

这样,当用户长按时,整个消息气泡会作为一个整体被“吸起”并呈现预览,视觉上更加统一和符合直觉。

在预览中提供实时交互:如果你的预览是一个自定义的视图控制器(UIViewController),你甚至可以在预览界面中加入一些轻量级的交互。例如,在照片预览中支持轻扫切换,或者在链接预览中提供一个“在Safari中打开”的按钮。这通过预览控制器的生命周期方法和添加子视图来实现,将简单的菜单交互扩展成了一个微型的临时功能界面。

5. 实战:复杂场景下的状态管理与性能优化

当你的应用中有大量可交互视图,或者菜单内容需要根据应用状态动态变化时,就需要更精细的设计。

动态菜单生成:菜单内容不应在配置方法中硬编码。它应该根据当前的数据模型和业务状态实时生成。例如,一个文件列表项,根据文件是否已下载、是否可编辑来显示不同的菜单。

func contextMenuInteraction(_ interaction: UIContextMenuInteraction,
                           configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
    guard let cell = interaction.view as? FileCell,
          let file = cell.fileModel else { return nil }

    var menuActions: [UIAction] = []

    // 根据文件状态动态添加动作
    if file.isDownloaded {
        let openAction = UIAction(title: "打开", image: UIImage(systemName: "play")) { _ in /*...*/ }
        menuActions.append(openAction)

        let shareAction = UIAction(title: "分享", image: UIImage(systemName: "square.and.arrow.up")) { _ in /*...*/ }
        menuActions.append(shareAction)
    } else {
        let downloadAction = UIAction(title: "下载", image: UIImage(systemName: "arrow.down.circle")) { _ in /*...*/ }
        menuActions.append(downloadAction)
    }

    if file.isEditable {
        let renameAction = UIAction(title: "重命名", image: UIImage(systemName: "pencil")) { _ in /*...*/ }
        menuActions.append(renameAction)
    }

    let deleteAction = UIAction(title: "删除", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in /*...*/ }
    menuActions.append(deleteAction)

    let menu = UIMenu(children: menuActions)
    return UIContextMenuConfiguration(identifier: file.id as NSCopying, previewProvider: nil) { _ in menu }
}

使用Identifier进行精准更新:注意上面代码中UIContextMenuConfiguration的identifier参数。它通常被忽略,但在动态内容场景下非常有用。当你的数据模型发生变化时,你可以通知系统更新特定视图的菜单。

// 假设文件下载完成,需要刷新该单元格的菜单
if let cell = tableView.cellForRow(at: indexPath) as? FileCell {
    // 使该单元格的上下文菜单配置失效,系统会在下次交互时重新请求
    UIContextMenuInteraction.updateVisibleMenu { /* 可在此闭包内更新菜单 */ }
    // 或者,更直接地,如果你存储了interaction的引用
    // cell.contextMenuInteraction?.updateVisibleMenu { ... }
}

性能考量:contextMenuInteraction(_:configurationForMenuAt:) 会在每次交互准备开始时调用。确保这个方法执行迅速,避免在其中进行耗时的网络请求或复杂计算。如果需要基于异步数据构建菜单,可以考虑先返回一个包含“加载中”状态的简易菜单,待数据获取后再更新。

最后,记得在真机上充分测试。触觉反馈(UIImpactFeedbackGenerator)、菜单弹出的流畅度、以及与其它手势(如滚动)的冲突处理,这些细节只有在真实设备上才能获得最准确的体验反馈。我在重构一个已有项目的长按菜单时,就曾因为忽略了UILabel的userInteractionEnabled属性,花了半小时排查菜单为何不弹出。另一个常见的坑是,在可滚动的视图(如UITableView)中,需要处理好长按手势与滚动手势的识别优先级,确保两者能和谐共存。

iOS开发进阶:利用UIContextMenuInteraction实现UILabel长按复制功能 本文详细介绍了在iOS开发中如何利用UIContextMenuInteraction为UILabel添加长按复制功能,提升用户体验。通过具体的代码示例和实现步骤,帮助开发者快速掌握这一技术,适用于设备信息管理等场景,显著提高操作便捷性。 阅读详情

相关推荐

告别3D Touch!UIContextMenuInteraction在UITableViewCell中的完整适配指南

本文详细介绍了在iOS开发中,如何利用UIContextMenuInteraction API为UITableViewCell适配现代化的上下文菜单,以全面取代已废弃的3D Touch方案。文章从核心协议、实战配置入手,深入讲解了动态菜单构建、预览视图控制、手势冲突解决等高级技巧,并提供了一份完整的适配检查清单,帮助开发者构建统一且强大的列表交互体验。

weixin_29202687的博客 115

iOS开发之上下文交互菜单(UIContextMenuInteraction)

在iOS13及以后的版本,苹果将用UIContextMenuInteraction取代上文中提到的Peek和Pop的功能,Peek和Pop的功能需要依赖硬件设备,UIContextMenuInteraction则摆脱了对硬件的依赖,本文将对UIContextMenuInteraction功能展开讲解。

郭永明的技术专栏 8648

35、MATLAB图形用户界面:uicontextmenu与uicontrol的使用指南

本文详细介绍了MATLAB中uicontextmenu和uicontrol的使用方法,涵盖其语法、属性设置、回调机制及实际应用示例。通过上下文菜单与多种UI控件的结合,帮助用户构建功能丰富、交互性强的图形用户界面,并提供了属性详解与流程图以辅助理解与开发。

blue42的博客 166

swift使用菜单_使用UIContextMenuInteraction在Swift中创建调试菜单

swift使用菜单Debug menus in iOS are a very effective way to make your day more productive as a developer. If you find yourself doing the same debugging tasks over and over, such as printing back-end respo...

weixin_26638123的博客 1007

Matlab:如何创建上下文菜单

现在当用户在图形上右键单击“打开”菜单项时,将会出现一个文件对话框,用户可以从中选择一个 MATLAB 文件或 MAT 文件来打开,当用户在图形上右键单击“保存”菜单项时,将会出现另一个文件对话框,用户可以从中选择一个目标文件名和位置,并将当前图形保存为 PNG 格式。创建自定义上下文菜单可以使您的 MATLAB 应用程序更加易于使用和灵活,通过使用回调函数,您可以将这些菜单项与实际的功能相连,从而为用户提供更多的选择和控制。可以让用户更加方便地访问您的功能,本文将为您介绍如何创建您自己的上下文菜单。

weixin_50547796的博客 281

chrome-headless-shell-mac-x64-160.0.8160.0(Canary).zip

内容概要:Chrome for Testing 官方 chrome-headless-shell 160.0.8160.0 x64 平台(金丝雀版通道),原版未修改,附来源说明。 适合人群:x64 上的自动化测试工程师、爬虫开发者、CI 环境搭建者。 使用场景及目标:①无头浏览器(Playwright/Puppeteer/Selenium 无界面自动化与爬虫的运行内核);②服务器/容器离线内置;③版本精准匹配(chromedriver 与 Chrome 需同大版本)。 其他说明:Chrome for Testing 为 Google 官方发布、允许自由分发的文件;本资源为第三方整理的下载便利服务。

【Material UI】Context Menu 详解

上下文菜单(Context Menu)是用户界面中常见的一种功能,当用户在特定区域内右键点击时会弹出菜单选项,用户可以在其中选择一个操作。的应用场景包括文件管理、文字编辑、表格操作等,能够有效提高用户操作的便捷性。Material UI 的Menu组件提供了高度灵活的 API,允许开发者根据具体需求自定义上下文菜单的外观和行为。接下来我们将深入探讨如何使用 Material UI 的Menu组件来实现一个简单且功能强大的。Menu组件是 Material UI 中提供的一个基础组件,用于创建弹出式菜单。

lph159的博客 1810

具有PWM控制VSC-HVDC链路的IEEE30总线传输系统(Simulink仿真实现)

内容概要:本文构建了一个包含PWM控制VSC-HVDC链路的IEEE30节点电力传输系统,并基于Simulink平台完成了系统的建模仿真。该模型聚焦于高压直流输电(HVDC)技术在区域电网互联中的应用,采用电压源型换流器(VSC)与脉宽调制(PWM)技术实现高效、灵活的电能传输。研究重点在于分析VSC-HVDC链路在复杂多节点电网中对潮流分布、系统稳定性及电能质量的调控能力,特别关注其在区域电网互联、新能源大规模接入以及跨区域电力交换等场景下的动态响应特性与控制性能,为现代智能电网的发展提供技术支撑与仿真验证手段。; 适合人群:具备电力系统、电气工程或自动化等相关专业背景的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于研究VSC-HVDC在多节点电网(如IEEE30节点)中的建模与仿真方法;②分析PWM控制策略下HVDC链路对电网潮流分布、电压稳定性和故障穿越能力的影响;③为区域电网互联、新能源并网及智能电网调度等课题提供仿真基础和技术验证。; 阅读建议:此资源以Simulink仿真实现为核心,建议读者在掌握电力电子技术和电力系统分析基础知识的前提下,结合仿真模型深入理解VSC-HVDC的工作原理与控制策略。在学习过程中,应着重关注模型参数设置、控制环路设计及仿真结果的分析,以达到理论与实践相结合的目的。

uimenu 菜单及设计

uimenu 菜单及设计 菜单是动态呈现的选择列表,它对应于相关方法(常称为命令)或GUI状态。菜单可以包含其他菜单或者菜单项,也可以包含菜单(即分层的菜单),表示可以执行的命令或所选择的GUI状态。菜单可以与应用程序的菜单栏相关,也可以漂浮在应用程序窗口之上,形成弹出式菜单。 1. 建立用户菜单 MATLAB的各个图形窗口有自己的菜单栏,包括File,Edit,Windows和Help等菜单项。为了建立用户自己的菜单系统,可以先将图形窗口的MenuBar属性事先设置为none,以取消图形窗口默认的菜单,然

逝年的博客 2090

基于KDE-CDF置信带的不确定综合能源系统鲁棒调度优化研究(Matlab代码实现)

内容概要:本研究针对不确定综合能源系统中的鲁棒调度优化问题,提出一种基于核密度估计-累积分布函数(KDE-CDF)置信带的建模方法,用以精确刻画风能、光伏及负荷等不确定性因素的非正态概率分布特征。通过构建KDE-CDF模型,能够有效捕捉实际运行中新能源出力与负荷需求的波动性与随机性,并在此基础上设计鲁棒优化调度框架,提升系统在不确定性环境下的运行可靠性与经济性。该方法结合Matlab编程实现,综合考虑系统运行成本、峰谷差、碳排放等多重目标,实现多维度协调优化。研究还探讨了与智能优化算法(如粒子群算法)相结合的应用路径,增强了模型的求解效率与工程实用性,为含多种储能装置、电转气设备及碳捕集系统的复杂综合能源系统提供了科学的调度决策支持。; 适合人群:具备电力系统分析、优化理论基础及Matlab编程能力的研究生、科研人员,以及从事综合能源系统规划、运行与调度工作的工程技术人员。; 使用场景及目标:①解决高比例可再生能源接入背景下综合能源系统调度中的不确定性建模难题;②提升调度方案在面对新能源强波动性时的鲁棒性与适应能力;③为融合多类型灵活性资源(如储能、电转气、碳捕集)的综合能源系统提供精细化、可落地的优化运行策略。; 阅读建议:建议读者在掌握概率统计、随机优化与电力系统运行基础知识的前提下,结合文中提供的Matlab代码进行实践操作,重点关注KDE-CDF置信带的构建流程及其在鲁棒优化模型中的嵌入机制,通过调整输入数据分布、参数设置与场景配置开展仿真对比实验,深入理解不确定性建模精度对调度决策质量的影响,进而掌握从数据驱动角度提升系统鲁棒性的关键技术路径。

从数据到特征:基于CAT12的MRI图像预处理实战指南

本文详细介绍了使用CAT12工具进行MRI图像预处理的完整实战流程。从数据获取、环境搭建到核心的AC-PC校正、组织分割、空间标准化与调制,逐步解析如何将原始脑影像数据转化为可用于机器学习的标准化特征图。重点阐述了预处理作为脑影像分析‘生命线’的重要性,并提供了避坑指南与自动化脚本建议,帮助研究者构建高质量的阿尔茨海默症分类模型输入特征。

weixin_29065959的博客 311

iOS13-新特性(PDF/Search/Menus)

黑客技术点击右侧关注,了解黑客的世界!Java开发进阶点击右侧关注,掌握进阶之路!Linux编程点击右侧关注,免费入门到精通!作者丨RayJiang97https://w...

iOS_开发 3063

XDS110 USB Debug Probe连接错误-260:CCS Theia环境下的诊断与修复指南

本文详细解析了CCS Theia环境下XDS110 USB Debug Probe连接错误-260的诊断与修复方法。从硬件连接到驱动状态、固件更新到软件配置,提供了全面的排查指南,帮助开发者快速解决这一常见的调试器通信障碍问题,确保嵌入式开发工作流畅进行。

hope8的博客 285

iOS开发之Context Menus

介绍 WWDC 2019 推出了上下文菜单(Context Menus)成为 3DTouch 的替代品。 需要通过长按方式触发。 如果要启用上下文菜单,需要创建一个 UIContextMenuInteraction 并将其添加给某个触发的 UIView,然后指定 delegate,实现代理方法。 代理方法需要返回一个UIContextMenuConfiguration,其构造函数如下init(identifier: NSCopying?, previewProvider: UIContextMenuCon

iOS-大鑫 711

Flowable多数据源实战:从配置到指定Schema的避坑指南

本文详细介绍了Flowable多数据源配置的实战指南,包括基础配置、数据源Bean创建、指定Schema的进阶配置以及常见问题排查。通过具体代码示例和避坑建议,帮助开发者高效实现多租户系统中的工作流引擎集成,特别强调了schema设置和事务管理的注意事项。

weixin_30824599的博客 486

深度探索:非线性随机森林(Nonlinear Random Forest,NL-RF)原理及应用

非线性随机森林(NL-RF)旨在通过结合集成方法与高级技术来捕捉和建模数据中的非线性关系,从而改善传统随机森林在处理复杂非线性数据结构时的表现。

qq_51320133的博客 2068

UI控件之菜单(Menu)

(一)概述 本章给大家带来的是Android中的Menu(菜单),而在Android中的菜单有如下几种:OptionMenu:选项菜单,android中最常见的菜单,通过Menu键来调用SubMenu:子菜单,android中点击子菜单将弹出一个显示子菜单项的悬浮框, 子菜单不支持嵌套,即不能包括其他子菜单ContextMenu:上下文菜单,通过长按某个视图组件后出现的菜单,该组件需注册上下文菜单

MakeYourChance的专栏 5200

无法联网的情况下,dbeaver离线安装数据库驱动-clickhouse

无法联网的情况下,dbeaver离线安装数据库驱动-clickhouse

u012831187的博客 1万+

iOS 14的UIMenu和ContextMenu中的新增功能

UIMenu was introduced in iOS 13 to allow easy creation of menus and submenus, which is really handy when building context menus. UIMenu是iOS 13中引入的,可轻松创建菜单和子菜单,这在构建上下文菜单时非常方便。 iOS 14 brings more custo...

weixin_26638123的博客 2673

MATLAB打开.m文件乱码解决办法

Matlab打开.m文件出现中文乱码问题,是因为Matlab存在两种编码格式:GBK和UTF-8,而不同版本的Matlab编码格式可能不统一,因此在不同版本的Matlab打开文件,由于编码格式的改变,会导致注释乱码。 1.查看你的Matlab的文件编码方式,在Matlab的命令行窗口输入feature('locale') ,如下图,可以看到默认编码为GBK,那问题就变成了将Matlab的文件编码方式GBK修改成UTF-8; 2.找到你的Matlab安装目录bin文件夹下的lcdata_utf.

zhugby的博客 4万+

TPAMI 2024 | 基于外观的深度学习凝视估计:综述与基准测试

人类目光提供了关于人类焦点和意图的有价值信息,使其成为研究的关键领域。最近,深度学习彻底改变了基于外观的眼神估计。然而,由于眼神估计研究的独特特征,如2D眼神位置和3D眼神向量之间的不公平比较以及不同的预处理和后处理方法,缺乏开发基于深度学习的眼神估计算法的明确指导方针。在本文中,我们系统回顾了使用深度学习的眼神估计方法。首先,我们沿着典型的眼神估计流程调查现有的算法:深度特征提取、深度学习模型设计、个人校准和平台。

小白学视觉 345

iOS 13+ 实战:用UIContextMenuInteraction打造优雅的上下文菜单(附二级菜单技巧)

本文详细介绍了在iOS 13+中使用UIContextMenuInteraction创建优雅上下文菜单的实战技巧,包括二级菜单的实现和性能优化。通过代码示例和最佳实践,帮助开发者提升应用交互体验,打造符合苹果设计规范的菜单系统。

i8j9k0l1的博客 460

【人工智能时代】-什么是MCP?本地如何开发MCP Server

MCP(Model Context Protocol)全称模型上下文协议,是由 Anthropic 推出的一种开放标准,旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。掌握更多的信息控制更多的工具在没有联网搜索之前,大模型的数据来源只有训练数据的时候以及推理我们告诉他的东西。所以后来的rag、知识库都是让AI掌握更多的信息,而MCP的出现是为了让大模型控制更多的工具,赋予更多能力。在本篇文章中,基于 Python 完成了一个简单的 MCP Server 的开发。

xiaoli8748的专栏 1994

MATLAB GUI自定义菜单栏uimenu,右键菜单uicontextmenu,下拉菜单popupmenu

有关于Matlab GUI菜单设计的总结

肆拾伍的博客 3541

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

M文件实现GUI菜单结构----UImenu、UIcontextmenu、UIcontrol

h = figure; set(h,'unit','normalized','color','default',...     'position',[0.1 0.1 0.8 0.8],'menu','none',...     'numbertitl','off','name','GUI 生成菜单'); h1 = uimenu(h,'label','一级菜单'); % h1 = uim

蓝天萝卜 1831

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

上一篇: TSG(The Spectral Geologist)实战指南:从零构建与动态修正MASK
下一篇: 手把手教你用Python实现Bowyer-Watson算法:从理论到代码实践
gitlab7runner
博客等级 码龄4年 78粉丝 1747原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值