Swift如何移除UIContextMenu消失动画中显示的阴影
全局移除所有UIContextMenu阴影
UIContextMenu的默认阴影全部附着在私有类UIPreviewContainerView的图层上,你可以通过方法交换全局修改该类实例的阴影属性:
import UIKit private func swizzleMethod(for clazz: AnyClass, originalSel: Selector, swizzledSel: Selector) { guard let originalMethod = class_getInstanceMethod(clazz, originalSel), let swizzledMethod = class_getInstanceMethod(clazz, swizzledSel) else { return } method_exchangeImplementations(originalMethod, swizzledMethod) } extension UIView { /// 全局关闭UIContextMenu阴影,建议在App启动时调用一次 static func disableGlobalContextMenuShadow() { guard let previewContainerCls = NSClassFromString("UIPreviewContainerView") as? UIView.Type else { return } swizzleMethod(for: previewContainerCls, originalSel: #selector(didMoveToWindow), swizzledSel: #selector(ss_disableShadow_didMoveToWindow)) } @objc private func ss_disableShadow_didMoveToWindow() { ss_disableShadow_didMoveToWindow() // 清除当前视图阴影 layer.shadowOpacity = 0 layer.shadowRadius = 0 // 清除所有子视图阴影 subviews.forEach { subview in subview.layer.shadowOpacity = 0 subview.layer.shadowRadius = 0 } } }
你只需要在AppDelegate的didFinishLaunchingWithOptions方法中调用UIView.disableGlobalContextMenuShadow()即可全局生效,不会影响其他控件的阴影效果。
单页面/单菜单禁用阴影
如果不需要全局修改,可以自定义上下文菜单的预览视图,直接关闭预览阴影:
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { let config = UIContextMenuConfiguration(identifier: indexPath as NSCopying, previewProvider: { [weak self] in guard let self = self, let cell = self.tableView.cellForRow(at: indexPath) else { return nil } // 复制cell内容作为预览 let previewView = cell.snapshotView(afterScreenUpdates: false) let previewVC = UIViewController() previewVC.view = previewView previewVC.view.layer.shadowOpacity = 0 previewVC.preferredContentSize = cell.bounds.size return previewVC }, actionProvider: { _ in // 你的菜单操作配置 return UIMenu(title: "", children: []) }) return config }
如果还是有退场阴影残留,可以额外实现两个预览代理方法,完全接管入场退场的预览效果:
// 高亮预览 func tableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { guard let indexPath = configuration.identifier as? IndexPath, let cell = tableView.cellForRow(at: indexPath) else { return nil } let parameters = UIPreviewParameters() parameters.backgroundColor = .clear parameters.shadowPath = nil // 强制关闭阴影 return UITargetedPreview(view: cell, parameters: parameters) } // 退场预览 func tableView(_ tableView: UITableView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { return self.tableView(tableView, previewForHighlightingContextMenuWithConfiguration: configuration) }
内容的提问来源于stack exchange,提问作者Oscar Junius
相关产品推荐
相关产品推荐

