从子视图控制器获取容器视图的故事板标识符

Posted

技术标签:

【中文标题】从子视图控制器获取容器视图的故事板标识符【英文标题】:Get Storyboard identifier of Container View from child View Controller 【发布时间】:2021-06-03 17:37:16 【问题描述】:

我在 MacOS (Xcode/AppKit) 上有多个容器视图,它们都将 segue 嵌入到同一个 PistonViewController 类,如下图所示。

每个容器视图都有一个标识符,例如“multiPiston1,multiPiston2”等... 我希望 PistonViewController 有一组带有 IBActions 的按钮。在按钮操作时,我想获取正确容器视图的标识符,以便知道操作发生在哪个视图中。

我在 PistonViewController 类中尝试了以下方法:

class pistonViewController: NSViewController 
...
    @IBAction func pistonClick(_ sender: NSButton) 
    if self.view.identifier == NSUserInterfaceItemIdentifier(rawValue: "multiPiston1")
    
    if self.parent.identifier == NSUserInterfaceItemIdentifier(rawValue: "multiPiston1")
    
    if self.parent.view.identifier == NSUserInterfaceItemIdentifier(rawValue: "multiPiston1") 
 

所有这些在打印时都给出了错误的标识符。那么如何找到这个标识符呢?

编辑:或者,每个嵌入 segue 都是独立的 - 如果我能以某种方式获得嵌入 segue 的标识符,那么我还可以找出正在使用的容器视图。

编辑:(我的理解)关系网。

视图控制器:MainController -> PistonViewController

NSViews: MainControllerView -> ContainerView -> PistonView(PistonViewController 的视图)

【问题讨论】:

你试过self.view.superview.identifier吗? 【参考方案1】:

您可以在 Storyboard 上为每个容器设置恢复 ID 并像这样使用

class ContainerViewController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()

    print(self.restorationIdentifier)
    

Set Restoration ID here

【讨论】:

恢复 ID 仅适用于 ViewControllers...ContainerView 是一个 View (NSView)【参考方案2】:

NSViewControllers 和 NSViews 存在于不同的域中,可以这么说。所以由于 ContainerView 不是 ViewController,为了解决这个问题就需要通过 NSView 进行通信。

子类化ContainerView并在子视图中设置标识属性,即PistonViewController的NSView:

class ContainerView1: NSView 

    override func draw(_ dirtyRect: NSRect) 
        super.draw(dirtyRect)

        // Drawing code here.
    
    override func viewDidMoveToWindow() 
         //print("hello???")
        print(self.subviews)
        let rail = self.subviews[0] as! pistonRail
        rail.container_id = self.identifier?.rawValue
    

PistonViewController 的视图子类:

class pistonRail: NSView 
    var container_id: String?
   
    override func draw(_ dirtyRect: NSRect) 
        super.draw(dirtyRect)

        // Drawing code here.
    

通过self.view访问PistonViewController的NSView属性:

class pistonViewController: NSViewController 
    @IBAction func pistonClick(_ sender: NSButton) 
            
            let pistonRail = self.view as! pistonRail
            print("view id: " + (pistonRail.container_id ?? "no"))
        

【讨论】:

以上是关于从子视图控制器获取容器视图的故事板标识符的主要内容,如果未能解决你的问题,请参考以下文章

'故事板“ Main”中的标识符为“”的实例化视图控制器,但尝试以模态方式显示视图控制器时未获得UITableView']

故事板例外 - 故事板不包含带有标识符的视图控制器

返回故事板当前视图控制器标识符

如何制作没有 xib 或故事板 vc 标识符的视图控制器?

如何修改故事板创建的视图控制器?

来自故事板的表格视图单元原型未初始化子视图