设置 nspopover 的位置
Set position of nspopover
我有一个视图控制器 (A),它将显示另一个 viewcontroller (B) 作为弹出窗口。
在我的 VC (A) 中是一个带有此 IBAction 的 NSButton:
self.presentViewController(vcPopover, asPopoverRelativeTo: myButton.bounds, of: myButton, preferredEdge: .maxX, behavior: .semitransient)
结果:
现在我想更改弹出窗口的位置 - 我想将其上移。
我试过这个:
let position = NSRect(origin: CGPoint(x: 100.0, y: 120.0), size: CGSize(width: 0.0, height: 0.0))
self.presentViewController(vcPopover, asPopoverRelativeTo: position, of: myButton, preferredEdge: .maxX, behavior: .semitransient)
但是位置没有变化
另一个例子
我有一个分段控件。如果您单击段“1”,将显示一个弹出窗口(与上面的代码相同)。但是箭头指向段“2”而不是段“1”
首先,确保您的弹出窗口确实是一个 NSPopover
而不是简单的 NSViewController
。假设您要包装在弹出窗口中的视图控制器的故事板 ID 为 "vcPopover",获取内容 vc 将如下所示:
let popoverContentController = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil).instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "vcPopover")) as! NSViewController
然后,将其包裹在弹出窗口中:
let popover = NSPopover()
popover.contentSize = NSSize(width: 200, height: 200) // Or whatever size you want, perhaps based on the size of the content controller
popover.behavior = .semitransient
popover.animates = true
popover.contentViewController = popoverContentController
然后,为了演示,调用 show(relativeTo:of:preferredEdge:)
:
vcPopover.show(relativeTo: myButton.bounds, of: myButton, preferredEdge: .maxX)
这应该会更新弹出窗口的位置。
更新: 您可能使用了 NSSegmentedControl
,这意味着您需要特别注意您在 show
中传递的矩形。您需要在描述分段区域的分段控件的坐标系 内传递边界矩形 。这是一个详细的例子:
// The view controller doing the presenting
class ViewController: NSViewController {
...
var presentedPopover: NSPopover?
@IBAction func selectionChanged(_ sender: NSSegmentedControl) {
let segment = sender.selectedSegment
if let storyboard = storyboard {
let contentVC = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("vcPopover")) as! NSViewController
presentedPopover = NSPopover()
presentedPopover?.contentSize = NSSize(width: 200, height: 200)
presentedPopover?.behavior = .semitransient
presentedPopover?.animates = true
presentedPopover?.contentViewController = contentVC
}
presentedPopover?.show(relativeTo: sender.relativeBounds(forSegment: segment), of: sender, preferredEdge: .minY)
}
}
extension NSSegmentedControl {
func relativeBounds(forSegment index: Int) -> NSRect {
// Assuming equal widths
let segmentWidth = bounds.width / CGFloat(segmentCount)
var rect = bounds
rect.size.width = segmentWidth
rect.origin.x = rect.origin.x + segmentWidth * CGFloat(index)
return rect
}
}
请注意 NSSegmentedControl
的扩展使用宽度计算线段的近似矩形。此方法假定宽度相等并且不考虑边框。您可以修改此方法以说明您的需要。有关获取 iOS 段的帧的信息(类似)可以在 here.
中找到
只要同一故事板中存在视图控制器且故事板标识符为 "vcPopover"。
,此示例将被验证为正常工作
我有一个视图控制器 (A),它将显示另一个 viewcontroller (B) 作为弹出窗口。
在我的 VC (A) 中是一个带有此 IBAction 的 NSButton:
self.presentViewController(vcPopover, asPopoverRelativeTo: myButton.bounds, of: myButton, preferredEdge: .maxX, behavior: .semitransient)
结果:
现在我想更改弹出窗口的位置 - 我想将其上移。
我试过这个:
let position = NSRect(origin: CGPoint(x: 100.0, y: 120.0), size: CGSize(width: 0.0, height: 0.0))
self.presentViewController(vcPopover, asPopoverRelativeTo: position, of: myButton, preferredEdge: .maxX, behavior: .semitransient)
但是位置没有变化
另一个例子
我有一个分段控件。如果您单击段“1”,将显示一个弹出窗口(与上面的代码相同)。但是箭头指向段“2”而不是段“1”
首先,确保您的弹出窗口确实是一个 NSPopover
而不是简单的 NSViewController
。假设您要包装在弹出窗口中的视图控制器的故事板 ID 为 "vcPopover",获取内容 vc 将如下所示:
let popoverContentController = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil).instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "vcPopover")) as! NSViewController
然后,将其包裹在弹出窗口中:
let popover = NSPopover()
popover.contentSize = NSSize(width: 200, height: 200) // Or whatever size you want, perhaps based on the size of the content controller
popover.behavior = .semitransient
popover.animates = true
popover.contentViewController = popoverContentController
然后,为了演示,调用 show(relativeTo:of:preferredEdge:)
:
vcPopover.show(relativeTo: myButton.bounds, of: myButton, preferredEdge: .maxX)
这应该会更新弹出窗口的位置。
更新: 您可能使用了 NSSegmentedControl
,这意味着您需要特别注意您在 show
中传递的矩形。您需要在描述分段区域的分段控件的坐标系 内传递边界矩形 。这是一个详细的例子:
// The view controller doing the presenting
class ViewController: NSViewController {
...
var presentedPopover: NSPopover?
@IBAction func selectionChanged(_ sender: NSSegmentedControl) {
let segment = sender.selectedSegment
if let storyboard = storyboard {
let contentVC = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("vcPopover")) as! NSViewController
presentedPopover = NSPopover()
presentedPopover?.contentSize = NSSize(width: 200, height: 200)
presentedPopover?.behavior = .semitransient
presentedPopover?.animates = true
presentedPopover?.contentViewController = contentVC
}
presentedPopover?.show(relativeTo: sender.relativeBounds(forSegment: segment), of: sender, preferredEdge: .minY)
}
}
extension NSSegmentedControl {
func relativeBounds(forSegment index: Int) -> NSRect {
// Assuming equal widths
let segmentWidth = bounds.width / CGFloat(segmentCount)
var rect = bounds
rect.size.width = segmentWidth
rect.origin.x = rect.origin.x + segmentWidth * CGFloat(index)
return rect
}
}
请注意 NSSegmentedControl
的扩展使用宽度计算线段的近似矩形。此方法假定宽度相等并且不考虑边框。您可以修改此方法以说明您的需要。有关获取 iOS 段的帧的信息(类似)可以在 here.
只要同一故事板中存在视图控制器且故事板标识符为 "vcPopover"。
,此示例将被验证为正常工作