【问题标题】:How to make controller in NSToolbar moving with NSSplitViewController's view like Reeder or Mail.app如何使 NSToolbar 中的控制器与 NSSplitViewController 的视图(如 Reeder 或 Mail.app)一起移动
【发布时间】:2016-01-22 01:04:15
【问题描述】:

我正在开发一个可可应用程序。它包含一个带有一些功能按钮的工具栏。就像里德一样。

我想在调整拆分视图大小的同时调整工具栏部分的大小。如下所示。如何实现这种功能?

任何人可以帮助我或提供一些建议将不胜感激。

我正在使用 XCode7、Swift 和 Storyboard 进行开发。

【问题讨论】:

    标签: xcode cocoa autolayout nssplitview nstoolbar


    【解决方案1】:

    显然没有任何方法可以将 splitView 添加到工具栏本身,我怀疑我们在 reeder 中看到的不是标准工具栏。无论如何,为了得到这个,我做了以下

    1. 主控制器上的隐藏标题栏、透明工具栏和全屏视图

    1. 将高度为 38 的自定义视图添加到“源列表(侧边栏)、内容列表(索引列表)和 SplitViewController splitView 项的默认区域的最顶部。然后向此 splitView 添加按钮

    1. 这就是它在主窗口上的样子

    1. 如果您想获得完整的工具栏外观。使用 37 点高度(您添加按钮的那些)为您的所有 customView 创建一个出口并自定义背景,添加渐变和底部边框

    【讨论】:

    • Swift 5 更新。self.window!.titleVisibility = NSWindow.TitleVisibility.hidden self.window!.titlebarAppearsTransparent = true self.window!.styleMask.insert([.fullSizeContentView ])
    【解决方案2】:

    我已经为 Swift 3 调整了 livingstonef 的实现,还添加了缺少的 NSBezierPath 扩展:

    import Cocoa
    
    @IBDesignable class ToolbarCustomView: NSView {
    
        override func draw(_ dirtyRect: NSRect) {
            super.draw(dirtyRect)
    
            //The background
            let startingColor = NSColor(red: 232/256, green: 230/256, blue: 232/256, alpha: 1)
            let endingColor = NSColor(red: 209/256, green: 208/256, blue: 209/256, alpha: 1)
            let gradient = NSGradient(starting: startingColor, ending: endingColor)
    
            gradient?.draw(in: self.bounds, angle: 270)
    
            //The bottom border
            let borderPath = NSBezierPath()
            let startingPoint = NSPoint(x: dirtyRect.origin.x, y: 0)
            let stoppingPoint = NSPoint(x: dirtyRect.width, y: 0)
    
            borderPath.move(to: startingPoint)
            borderPath.line(to: stoppingPoint)
    
            let shapeLayer = CAShapeLayer()
    
            self.layer?.addSublayer(shapeLayer)
    
            shapeLayer.path = borderPath.cgPath
            shapeLayer.strokeColor = NSColor(red: 180/256, green: 182/256, blue: 180/256, alpha: 0.6).cgColor
            shapeLayer.fillColor = .clear
            shapeLayer.lineWidth = 1
        }
    }
    
    extension NSBezierPath {
    
        public var cgPath: CGPath {
            let path = CGMutablePath()
            var points = [CGPoint](repeating: .zero, count: 3)
    
            for i in 0 ..< self.elementCount {
                let type = self.element(at: i, associatedPoints: &points)
                switch type {
                case .moveToBezierPathElement:
                    path.move(to: points[0])
                case .lineToBezierPathElement:
                    path.addLine(to: points[0])
                case .curveToBezierPathElement:
                    path.addCurve(to: points[2], control1: points[0], control2: points[1])
                case .closePathBezierPathElement:
                    path.closeSubpath()
                }
            }
    
            return path
        }
    }
    

    【讨论】:

    • 您实际上甚至不需要贝塞尔曲线来设置工具栏上的边框,您只需为图层添加边框即可。此外,当窗口不再是关键窗口时,您可能需要更改工具栏的渐变。这是一个更新的自定义工具栏,适用于 Swift 3.0 gist.github.com/livingstonef/04bc9344a501cf198db13d1e48a6addd
    • 感谢更新,关键窗口逻辑工作正常。除非我也将边框宽度设置为 1,否则我不会得到图层边框。但是边框在视图的所有侧面,而不仅仅是在底部。我错过了什么吗?
    【解决方案3】:

    一切都与约束有关

    如果工具栏在拆分视图中:

    在您的工具栏上设置约束“与最近邻的间距”,例如 0 表示左右 然后该按钮还必须与工具栏有一个“到最近邻居的间距”,例如右侧的 8

    编辑:在此处查看按钮以添加约束http://oi63.tinypic.com/2s7szgi.jpg

    【讨论】:

    • 对不起,我不明白你的意思。你说的是哪个按钮?我想知道如何使分段控件与拆分视图的分隔符一起移动。他们似乎是正确的。我不知道它们是否可以相互添加任何约束。非常感谢你。如果您能给我更多帮助,我们将不胜感激。
    • 在底部您可以为每个选定对象设置约束oi63.tinypic.com/2s7szgi.jpg
    • 1.工具栏中的控制器不能添加任何约束。 2.下方的SplitView和工具栏甚至不属于同一个父视图。如何向它们添加约束?
    • 约束不在控制器上,但在视图中一个视图,保持 Ctrl 并将箭头移动到另一个视图
    • 对不起我的英语不好。我提到的,工具栏是应用程序的主工具栏。而拆分视图是窗口的内容视图。我认为他们不能一起使用约束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    相关资源
    最近更新 更多