0

我有一个经典的垂直 NSSplitViewController 并且在窗格约束中没有成功。

如果右窗格中没有任何内容,我可以毫无问题地调整窗口大小,左窗格的宽度不会改变。

在此处输入图像描述

但是,如果我在右窗格中有一个视图,并且我想调整窗口大小以使右窗格的宽度更大,则调整大小的是左窗格:

在此处输入图像描述

我知道这是一个约束问题,但我不知道如何解决这些约束。

在拆分视图控制器中,我有以下代码:

class splitViewController: NSSplitViewController {

    private var verticalConstraints: [NSLayoutConstraint] = []
    private var horizontalConstraints: [NSLayoutConstraint] = []
    
    private var treeControllerObserver: NSKeyValueObservation?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleSelectionChange(_:)),
            name: Notification.Name(OutlineViewController.NotificationNames.selectionChanged),
            object: nil)
        splitView.autosaveName = "SplitViewAutoSave"
    }
    
    // MARK: - Detail View Controller Management
    
    private var detailViewController: NSViewController {
        let rightSplitViewItem = splitViewItems[1]
        return rightSplitViewItem.viewController
    }
    
    private var hasChildViewController: Bool {
        return !detailViewController.children.isEmpty
    }
    
    private func embedChildViewController(_ childViewController: NSViewController) {
        // This embeds a new child view controller.
        let currentDetailVC = detailViewController
        currentDetailVC.addChild(childViewController)
        currentDetailVC.view.addSubview(childViewController.view)
        
        // Build the horizontal, vertical constraints so that an added child view controller matches the width and height of its parent.
        let views = ["targetView": childViewController.view]
        horizontalConstraints =
            NSLayoutConstraint.constraints(withVisualFormat: "H:|[targetView]|",
                                           options: [],
                                           metrics: nil,
                                           views: views)
        NSLayoutConstraint.activate(horizontalConstraints)
        
        verticalConstraints =
            NSLayoutConstraint.constraints(withVisualFormat: "V:|[targetView]|",
                                           options: [],
                                           metrics: nil,
                                           views: views)
        NSLayoutConstraint.activate(verticalConstraints)
    }
    
    //MARK: - Notifications
    
    // Listens for selection changes to the NSTreeController.
    @objc
    private func handleSelectionChange(_ notification: Notification) {
        // Examine the current selection and adjust the UI.
        
        // Make sure the notification's object is a tree controller.
        guard let outlineView = notification.object as? NSOutlineView else { return }
        
        let leftSplitViewItem = splitViewItems[0]
        if let outlineViewControllerToObserve = leftSplitViewItem.viewController as? OutlineViewController {
            let currentDetailVC = detailViewController
            
            // Let the outline view controller handle the selection (helps you decide which detail view to use).
            if let vcForDetail = outlineViewControllerToObserve.viewControllerForSelection(outlineView.selectedRowIndexes) {
                if hasChildViewController && currentDetailVC.children[0] != vcForDetail {
                    /** The incoming child view controller is different from the one you currently have,
                        so remove the old one and add the new one.
                    */
                    currentDetailVC.removeChild(at: 0)
                    // Remove the old child detail view.
                    detailViewController.view.subviews[0].removeFromSuperview()
                    // Add the new child detail view.
                    embedChildViewController(vcForDetail)
                } else {
                    if !hasChildViewController {
                        // You don't have a child view controller, so embed the new one.
                        embedChildViewController(vcForDetail)
                    }
                }
            } else {
                // No selection. You don't have a child view controller to embed, so remove the current child view controller.
                if hasChildViewController {
                    currentDetailVC.removeChild(at: 0)
                    detailViewController.view.subviews[0].removeFromSuperview()
                }
            }
        }
    }
 
}

(我在旧的 stackoverflow 答案中找到了代码,我已经复制了它,但我不习惯编写约束,因为它是在 embedViewController 方法中编写的。

我确切地说,在 IB 中,我将窗格的持有优先级约束固定如下:左窗格为 200,右窗格为 199

有人能帮我吗?

4

0 回答 0