Autolayout 不适用于带有 Storyboard 的 NSSplitView 和 NSPageController。这是苹果虫吗?

Posted

技术标签:

【中文标题】Autolayout 不适用于带有 Storyboard 的 NSSplitView 和 NSPageController。这是苹果虫吗?【英文标题】:Autolayout is not working with NSSplitView and NSPageController with Storyboard. Is this Apple Bug? 【发布时间】:2015-09-01 07:00:12 【问题描述】:

我刚刚在github上创建了一个空项目 --> here

该项目是一个简单的故事板项目。一个 NSWindowController 加载一个 NSPageController 加载一个包含 3 个窗格的 NSSplitView。示例项目中没有代码,除了加载屏幕的代码。当项目运行时,它看起来像这样。

当调整窗口大小时,如何获得约束以使 splitView 一直延伸到末端?奇怪的是,如果你将 NSWindowController 的 contentController 从 NSPageController 切换到 NSSplitViewController,那么一切都按预期工作。这是苹果虫吗?我将不胜感激任何答案 swift/objectivec 请。我试过了,但没有任何效果。

[编辑] - 根据下面的答案和进一步的研究(联系 Apple),似乎 NSPageViewController 不使用自动布局约束,而是依赖于其子视图的自动调整掩码和框架设置。

所以当页面控制器创建它的视图控制器时,我们应该这样设置:

-(NSViewController *)pageController:(NSPageController *)pageController viewControllerForIdentifier:(NSString *)identifier 
    NSViewController *viewController = [self.storyboard instantiateControllerWithIdentifier:identifier];
    [viewController.view setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)];
    return viewController;

这样,问题就解决了。我希望作为未来的更新,此控件适用于 Autolayout 约束,因为它看起来更自然。

【问题讨论】:

【参考方案1】:

NSPageController 有很多问题。我发现解决方案是不使用自动布局。

尝试在您的NSSplitView 上使用NSAutoresizingMaskOptions。 首先,删除NSPageController 中的所有约束。

然后:

splitView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
splitView.frame = pageController.view.bounds;

splitView.autoresizingMask = [.ViewWidthSizable, .ViewHeightSizable]
splitView.frame = pageController.view.bounds

编辑

根据你的here做了一个项目

【讨论】:

嗨,好的,我把这个放在我的代码哪里?我已经尝试将它放入我的代码中,但它不起作用。我有上面相同的代码,你介意告诉我放在哪个部分? 我在持有 NSPageController 的主视图控制器的 viewDidLoad 中使用了它。 好的。一个问题,你的意思是你在你的代码中以这种方式使用它吗?还是您的意思是您在我上面提供的代码中使用了它?因为在我上面提供的代码中,viewDidLoad 没有对 splitView 的引用。。上面的引用代码也使用了故事板 对不起,我错过了你的代码。我查看了它,但无法修复它。视图大小合适,但是当有多个控制器时,错误仍然存​​在 - 我明天会看看它 你的答案是正确的。如果您不更新发布的答案以反映您在代码中所做的事情,那么我会稍后再做。谢谢一百万!【参考方案2】:

我在 Pagecontroller 中也遇到了同样的问题:

并使用给定的代码解决了它:

 func pageController(_ pageController: NSPageController, viewControllerForIdentifier identifier: String) -> NSViewController 
    switch identifier 
    case "formController":
        let controller = NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "formController") as! FormController
        controller.view.autoresizingMask = [.height , .width]
        return controller
    default:
        return self.storyboard?.instantiateController(withIdentifier: identifier) as! NSViewController
    


func pageController(_ pageController: NSPageController, identifierFor object: Any) -> String 

    return String(describing: object)



func pageControllerDidEndLiveTransition(_ pageController: NSPageController) 
    print(pageController.selectedIndex)

    pageController.completeTransition()
     pageController.selectedViewController!.view.autoresizingMask = [.height , .width]


【讨论】:

以上是关于Autolayout 不适用于带有 Storyboard 的 NSSplitView 和 NSPageController。这是苹果虫吗?的主要内容,如果未能解决你的问题,请参考以下文章

AutoLayout 适用于 UIView 但不适用于 UILabel。为啥?

自动布局不适用于可重用的表格视图单元格

UIScrollView 不使用 AutoLayout 滚动

带有 RemoteViews 的 setBackgroundResource 不适用于布局

溢出:隐藏;不适用于带有 IFRAME 的 Chrome?

阴影不适用于带有蒙版的 UIViewLayer