日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

底部菜单 点击突起_iOS开发之上下文交互菜单(UIContextMenuInteraction)

發(fā)布時間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 底部菜单 点击突起_iOS开发之上下文交互菜单(UIContextMenuInteraction) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 概述

在iOS13及以后的版本,蘋果將用UIContextMenuInteraction取代上文中提到的Peek和Pop的功能,Peek和Pop的功能需要依賴硬件設(shè)備,UIContextMenuInteraction則擺脫了對硬件的依賴。


在iOS9以及iPhone6s及以上的設(shè)備上,蘋果推出了Peek和Pop功能,并在預(yù)覽時上滑提供可供操作的操作菜單。在iOS13及以后,蘋果禁用了UIViewControllerPreviewing協(xié)議相關(guān)方法,取而代之的則是UIContextMenuInteraction,如果項目最低運行版本是iOS13,且調(diào)用了UIViewControllerPreviewing協(xié)議相關(guān)方法,那么系統(tǒng)將會有黃色的警告,如果UIContextMenuInteraction和UIViewControllerPreviewing協(xié)議方法同時使用,系統(tǒng)只會采用UIContextMenuInteraction。

2. 上下文菜單(Context Menu)


在所有運行iOS13(及以上系統(tǒng))的設(shè)備上,蘋果都為其提供了上下文菜單功能,用戶可以通過長按或者3D Touch(如果硬件支持)方式,彈出一個帶可操作菜單的預(yù)覽界面。
上下文菜單可以創(chuàng)建二級菜單,但是處于自動布局考慮,蘋果還是建議所有菜單盡量在同一級別。
下面看一下系統(tǒng)相冊列表長按圖片的效果

圖中,長按后彈出一個預(yù)覽視圖,底部帶有操作選項列表,周邊全部虛化,如果點擊預(yù)覽圖,則可進(jìn)入全屏界面查看圖片。

2.1 一級菜單

要實現(xiàn)菜單的功能,則需要在控制器內(nèi)實現(xiàn)UIContextMenuInteractionDelegate的協(xié)議方法:

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

該方法為協(xié)議中必須實現(xiàn)的一個方法,方法要求返回一個UIContextMenuConfiguration對象。這個對象配置了Context menu所需要的預(yù)覽圖以及操作事件等。具體看一下:

屬性或方法說明
var identifier: NSCopying初始化方法。
typealias UIContextMenuContentPreviewProvider該block中返回預(yù)覽視圖控制器。
typealias UIContextMenuActionProvider該block中返回可操作性的菜單。

舉個例子,在一個界面中,如下圖,按住button后彈出對圖片的操作選項。

在代理回調(diào)中創(chuàng)建一個UIContextMenuConfiguration對象,并添加對應(yīng)的Action事件,代碼如下:

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { (elements) -> UIMenu? inlet favoriteAction = UIAction(title: "喜歡", image: UIImage(systemName: "heart.fill"), state: .off) { (action) in}let shareAction = UIAction(title: "分享", image: UIImage(systemName: "square.and.arrow.up.fill"), state: .off) { (action) in}let deleteAction = UIAction(title: "刪除", image: UIImage(systemName: "trash.fill"),attributes: [.destructive], state: .off) { (action) in}return UIMenu(title: "菜單", children: [favoriteAction, shareAction, deleteAction])} }

然后還需要向button添加UIContextMenuInteraction對象,方可有長按住事件響應(yīng),代碼如下:

let interaction = UIContextMenuInteraction(delegate: self) button.addInteraction(interaction)

當(dāng)按住button后,效果如下:

以上則將Context Menu的一級菜單顯示出來了。
小結(jié)一下:

  • UIContextMenuInteraction: 添加一個context menu到指定的view。
  • UIContextMenuConfiguration: 配置一個帶有action列表的對象給context menu。
  • UIContextMenuInteractionDelegate: 管理context menu的整個周期,彈出、展示、銷毀。

2.2 二級菜單

二級菜單能夠使Context Menu更加簡潔、清晰明了。

下面在上面一級菜單的基礎(chǔ)上增加一個打分功能二級菜單,代碼如下:

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { (elements) -> UIMenu? in// 二級action數(shù)組var ratingActions: Array<UIAction> = []// 遍歷增加5個actionfor i in 0..<5 {let action = UIAction(title: "(i+1) 分") { (action) in}ratingActions.append(action)}// 創(chuàng)建一個打分的菜單let ratingMenu = UIMenu(title: "打分", image: UIImage(systemName: "star.circle"), children: ratingActions)let favoriteAction = UIAction(title: "喜歡", image: UIImage(systemName: "heart.fill"), state: .off) { (action) in}let shareAction = UIAction(title: "分享", image: UIImage(systemName: "square.and.arrow.up.fill"), state: .off) { (action) in}let deleteAction = UIAction(title: "刪除", image: UIImage(systemName: "trash.fill"),attributes: [.destructive], state: .off) { (action) in}// 將打分的菜單放到一級菜單里面。return UIMenu(title: "菜單", children: [ratingMenu, favoriteAction, shareAction, deleteAction])} }

運行效果圖如下,當(dāng)點擊“打分”后,轉(zhuǎn)入二級菜單界面。

除了二級菜單,還可以有三級、四級等菜單,寫法就是層層嵌套,不過不建議搞這么多層的菜單,影響用戶體驗。

2.3 分組菜單

分組菜單可以將類似的功能歸到一組,比如上面將刪除單獨歸到一組,只需將刪除的action包裝到UIMenu中,并設(shè)置UIMenu的Options屬性為displayInline即可,代碼如下:

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { (elements) -> UIMenu? in// 二級action數(shù)組var ratingActions: Array<UIMenuElement> = []// 遍歷增加5個actionfor i in 0..<5 {let action = UIAction(title: "(i+1) 分") { (action) in}ratingActions.append(action)}// 創(chuàng)建一個打分的菜單let ratingMenu = UIMenu(title: "打分", image: UIImage(systemName: "star.circle"), children: ratingActions)let favoriteAction = UIAction(title: "喜歡", image: UIImage(systemName: "heart.fill"), state: .off) { (action) in}let shareAction = UIAction(title: "分享", image: UIImage(systemName: "square.and.arrow.up.fill"), state: .off) { (action) in}let deleteAction = UIAction(title: "刪除", image: UIImage(systemName: "trash.fill"),attributes: [.destructive], state: .off) { (action) in}// 創(chuàng)建一個delete menu,然后設(shè)置options屬性為displayInline,并將上面的deleteAction添加進(jìn)來。let deleteMenu = UIMenu(title: "刪除菜單", options: .displayInline, children: [deleteAction])// 將打分的菜單放到一級菜單里面。return UIMenu(title: "菜單", children: [ratingMenu, favoriteAction, shareAction, deleteMenu])} }

運行效果圖如下:

3. 預(yù)覽視圖及點擊處理


預(yù)覽視圖可以快速的給用戶提供一些預(yù)覽信息。


上面的操作菜單是通過UIContextMenuConfiguration對象UIContextMenuActionProvider提供呢,那么預(yù)覽視圖則是通過UIContextMenuConfiguration對象的[UIContextMenuContentPreviewProvider](https://developer.apple.com/documentation/uikit/uicontextmenucontentpreviewprovider)提供的,同樣是在創(chuàng)建UIContextMenuConfiguration對象的協(xié)議方法里面。

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {return UIContextMenuConfiguration(identifier: nil) { [weak self] () -> UIViewController? in// 創(chuàng)建預(yù)覽視圖,并返回。let detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)detailVC.image = self?.imageView.image// 預(yù)覽視圖顯示大小detailVC.preferredContentSize = CGSize(width: 280, height: 360)return detailVC} actionProvider: { [weak self] (elements) -> UIMenu? inreturn self?.createContextMenuActions()} }

上面代碼中創(chuàng)建了一個DetailViewController對象,并給其傳遞數(shù)據(jù),用于預(yù)覽內(nèi)容,然后制定了預(yù)覽圖的大小。運行效果如下:

當(dāng)點擊底部action列表項的時候,自有對應(yīng)的action block處理點擊事件,那么如果點擊預(yù)覽圖,如何處理呢?下面看這個協(xié)議方法:

/*!* 當(dāng)用戶點擊預(yù)覽圖的時候調(diào)用,相當(dāng)于3DTouch里面的Pop功能。** @param interaction 當(dāng)前的交互對象* @param configuration 當(dāng)前的配置項* @param animator 跳轉(zhuǎn)動畫執(zhí)行者,可以給它添加跳轉(zhuǎn)動畫。*/ func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating)

下現(xiàn)在將這個協(xié)議方法具體實現(xiàn)以下:

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {animator.addCompletion { [weak self] inif let this = self {let detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)detailVC.image = this.button.imageView?.imagethis.show(detailVC, sender: nil)}} }

添加了上面的方法后,在運行點擊預(yù)覽圖則會進(jìn)入DetailViewController界面,全屏展示圖片。

4. TableView中的Context Menu


TableView中的Context Menu,系統(tǒng)已經(jīng)進(jìn)行了封裝,我們不需要在創(chuàng)建和添加UIContextMenuInteraction對象了,如果實現(xiàn)了協(xié)議方法,那么按住cell的時候就會響應(yīng)協(xié)議方法。


相關(guān)協(xié)議方法如下:

func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating)

Demo參考代碼如下:

override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {let image = UIImage(named: imageArray[indexPath.row])return ImageContextMenuConfiguration.createInstance(indexPath.row, image)}override func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {if let index = Int(configuration.identifier as! String) {animator.addCompletion {[weak self]inlet detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)if let imageName = self?.imageArray[index] {detailVC.image = UIImage(named: imageName)}self?.show(detailVC, sender: nil)}} }

5. CollectionView中的Context Menu

CollectionView中的Context Menu,系統(tǒng)已經(jīng)進(jìn)行了封裝,我們不需要在創(chuàng)建和添加UIContextMenuInteraction對象了,如果實現(xiàn)了協(xié)議方法,那么按住cell的時候就會響應(yīng)協(xié)議方法。

相關(guān)協(xié)議方法如下:

func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? func collectionView(_ collectionView: UICollectionView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating)

Demo參考代碼如下:

override func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {let image = UIImage(named: imageArray[indexPath.row])return ImageContextMenuConfiguration.createInstance(indexPath.row, image)}override func collectionView(_ collectionView: UICollectionView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {if let index = Int(configuration.identifier as! String) {animator.addCompletion {[weak self]inlet detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)if let imageName = self?.imageArray[index] {detailVC.image = UIImage(named: imageName)}self?.show(detailVC, sender: nil)}} }

6. 總結(jié)


干巴巴的講了一堆,如果不配上Demo,都有點說不過去,需要Demo的點擊這里。
Context Menu主要用于預(yù)覽和快速操作,功能和3D Touch差不多,但是有意取代3D Touch,以減少對硬件的依賴。


本文主要對該功能做了簡單的說明,至于如何將該功能用的更好,還待日后具體研究了,文中如果有不對的地方,還請路過的朋友指正。


更多可操作的協(xié)議方法,詳見**UIContextMenuInteractionDelegate。**
對了,蘋果建議Context Menu采用系統(tǒng)提供的圖片符號(SF Symbols),喜歡的小伙伴可以安裝看看,鏈接為:developer.apple.com/sf-symbols/,根據(jù)自己電腦系統(tǒng),下載對應(yīng)的SF Symbols。

本篇文章出自blog.csdn.net/guoyongming…的博客,如需轉(zhuǎn)載,請標(biāo)明出處。


原文作者:Daniel_Coder
原文地址:https://blog.csdn.net/guoyongming925/article/details/110839969?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160766080119721940249352%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160766080119721940249352&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-12-110839969.pc_search_result_cache&utm_term=iOS%E5%BC%80%E5%8F%91&spm=1018.2118.3001.4449

總結(jié)

以上是生活随笔為你收集整理的底部菜单 点击突起_iOS开发之上下文交互菜单(UIContextMenuInteraction)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。