如何将UIMenu自定义为横向布局并实现图标下显示文字?
实现横向图标+下方文字的自定义菜单
可以实现iOS备忘录那种横向排列、图标下方带文字的菜单效果,本质是通过自定义popover弹窗而非系统默认UIMenu样式来实现,具体步骤如下:
步骤1:封装图标+下方文字的按钮组件
先做一个可复用的按钮,配置图标在上、文字在下的布局:
func createMenuButton(image: UIImage?, title: String) -> UIButton { var config = UIButton.Configuration.plain() config.image = image?.withRenderingMode(.alwaysTemplate) config.title = title config.imagePlacement = .top config.imagePadding = 4 config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in var outgoing = incoming outgoing.font = UIFont.systemFont(ofSize: 12) return outgoing } let button = UIButton(configuration: config) button.tintColor = .systemBlue button.addTarget(self, action: #selector(menuButtonTapped(_:)), for: .touchUpInside) return button } @objc func menuButtonTapped(_ sender: UIButton) { // 根据按钮标题区分执行对应操作 switch sender.titleLabel?.text { case "扫描": // 处理扫描逻辑 break case "固定": // 处理固定逻辑 break case "锁定": // 处理锁定逻辑 break default: break } // 关闭弹窗 sender.parentViewController?.dismiss(animated: true) }
步骤2:构建横向排列的菜单视图
用UIStackView横向组装多个按钮:
func createMenuView() -> UIView { let stackView = UIStackView() stackView.axis = .horizontal stackView.spacing = 24 stackView.distribution = .equalSpacing stackView.alignment = .center // 添加功能按钮 let scanBtn = createMenuButton(image: UIImage(systemName: "doc.text.viewfinder"), title: "扫描") let pinBtn = createMenuButton(image: UIImage(systemName: "pin"), title: "固定") let lockBtn = createMenuButton(image: UIImage(systemName: "lock"), title: "锁定") stackView.addArrangedSubview(scanBtn) stackView.addArrangedSubview(pinBtn) stackView.addArrangedSubview(lockBtn) // 设置内边距优化布局 stackView.layoutMargins = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) stackView.isLayoutMarginsRelativeArrangement = true return stackView }
步骤3:给导航栏按钮绑定弹窗逻辑
创建UIBarButtonItem,点击时弹出自定义popover:
// 初始化导航栏右侧按钮 let menuBarBtn = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"), style: .plain, target: self, action: #selector(showCustomMenu)) navigationItem.rightBarButtonItem = menuBarBtn @objc func showCustomMenu() { let menuView = createMenuView() // 弹窗容器控制器 let popupVC = UIViewController() popupVC.view = menuView popupVC.preferredContentSize = menuView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) // 配置popover样式 popupVC.modalPresentationStyle = .popover if let popover = popupVC.popoverPresentationController { popover.barButtonItem = navigationItem.rightBarButtonItem popover.permittedArrowDirections = .up } present(popupVC, animated: true) }
注意事项
UIButton.Configuration是iOS 15+API,若需兼容iOS 14及以下,可通过手动设置按钮的image、title,并添加约束实现图标在上、文字在下的布局。- 可根据需求调整按钮的字体、颜色、间距等样式,适配不同设计要求。
内容的提问来源于stack exchange,提问作者shuna
相关产品推荐
相关产品推荐

