如何创建指向上方视图的dialogue box,在stack view内动态pages icon下方显示
实现指向动态stack view内图标的定向弹窗方案

因为pages icon位于stack view中位置动态,所以不能写死坐标,优先通过绑定源视图的方式实现自适应锚定,以下是两种可行方案:
方案1:使用系统自带UIPopoverPresentationController(推荐,适配成本最低)
系统原生的popover控制器自带锚定任意视图的能力,会自动跟踪源视图的位置变化,无需手动计算坐标,适配横竖屏、布局更新等场景:
- 先创建弹窗的内容控制器,实现你需要的弹窗UI样式,包含顶部向上的尖角即可
- 配置popover属性并弹出,示例代码如下:
// 1. 初始化弹窗内容控制器 let popupContentVC = YourPopupViewController() popupContentVC.modalPresentationStyle = .popover // 2. 配置popover锚定规则 guard let popover = popupContentVC.popoverPresentationController else { return } // 直接绑定目标icon为源视图,系统会自动跟踪其位置变化 popover.sourceView = pagesIcon popover.sourceRect = pagesIcon.bounds // 设置弹窗箭头方向为向上,刚好指向正上方的pages icon popover.permittedArrowDirections = .up popover.delegate = self // 3. 弹出弹窗 present(popupContentVC, animated: true)
- 要实现iPhone端非全屏的弹窗效果,需要实现
UIPopoverPresentationControllerDelegate代理方法:
extension YourViewController: UIPopoverPresentationControllerDelegate { func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { // 禁用系统默认的iPhone端全屏适配 return .none } }
方案2:自定义弹窗(适合需要完全自定义样式的场景)
如果系统popover的样式不符合需求,可以手动实现自定义弹窗,步骤如下:
- 先获取pages icon在父视图中的真实坐标,用系统坐标系转换方法实现:
// 把icon的bounds从stack view的坐标系转换到当前控制器view的坐标系 let iconFrameInSuperView = pagesIcon.convert(pagesIcon.bounds, to: self.view) // 取icon底部中心点作为弹窗的锚点 let anchorPoint = CGPoint(x: iconFrameInSuperView.midX, y: iconFrameInSuperView.maxY)
- 计算弹窗的位置,做边界兼容避免内容超出屏幕:
let popupWidth: CGFloat = 200 // 你的弹窗宽度 let popupHeight: CGFloat = 150 // 你的弹窗高度 // 初始x坐标:让弹窗水平中心对齐锚点 var popupX = anchorPoint.x - popupWidth / 2 // 左边界兼容:不能超出屏幕左侧16pt的安全边距 if popupX < 16 { popupX = 16 } // 右边界兼容:不能超出屏幕右侧16pt的安全边距 if popupX + popupWidth > self.view.bounds.width - 16 { popupX = self.view.bounds.width - 16 - popupWidth } // 设置弹窗最终frame,y坐标在锚点下方加8pt间距 let popupFrame = CGRect(x: popupX, y: anchorPoint.y + 8, width: popupWidth, height: popupHeight) yourCustomPopupView.frame = popupFrame // 如果用自动布局,对应更新弹窗的leading、top约束,以及尖角的centerX约束对齐anchorPoint.x即可
- 布局更新回调适配:如果stack view的布局会动态变化(比如横竖屏切换、item数量增减),可以在
viewDidLayoutSubviews方法中重新计算弹窗位置,保证始终对齐pages icon。
内容的提问来源于stack exchange,提问作者Nupur Sharma
相关产品推荐
相关产品推荐

