如何使 NSToolbar 中的控制器随着 NSSplitViewController 的视图移动,如 Reeder 或 Mail.app
How to make controller in NSToolbar moving with NSSplitViewController's view like Reeder or Mail.app
我正在开发 cocoa 应用程序。它包含一个带有一些功能按钮的工具栏。就像里德一样。
我想在调整拆分视图大小时调整工具栏部分的大小。有些东西像下面这样工作。如何实现这种功能?
任何人都可以帮助我或提出一些建议,我们将不胜感激。
我正在使用 XCode7、Swift 和 Storyboard 进行开发。
一切都是关于约束的
如果工具栏在拆分视图中:
在您的工具栏上设置约束条件 "spacing to nearest neighbor",例如 0 代表左右
然后按钮也必须有一个 "spacing to nearest neighbor" 到工具栏,例如右边的 8
编辑:请参阅此处添加约束的按钮 http://oi63.tinypic.com/2s7szgi.jpg
显然没有任何方法可以将 splitView 添加到工具栏本身,我怀疑我们在 reeder 中看到的不是标准工具栏。无论如何要得到这个,我做了以下
- 主控制器隐藏标题栏、透明工具栏和全屏视图
- 将高度为 38 的自定义视图添加到每个“源列表(侧边栏)、内容列表(索引列表)和 SplitViewController splitView 项目的默认区域的最顶部。然后将按钮添加到此 splitView
- 这是它在主屏幕上的样子 window
我已经为 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
}
}
我正在开发 cocoa 应用程序。它包含一个带有一些功能按钮的工具栏。就像里德一样。
我想在调整拆分视图大小时调整工具栏部分的大小。有些东西像下面这样工作。如何实现这种功能?
任何人都可以帮助我或提出一些建议,我们将不胜感激。
我正在使用 XCode7、Swift 和 Storyboard 进行开发。
一切都是关于约束的
如果工具栏在拆分视图中:
在您的工具栏上设置约束条件 "spacing to nearest neighbor",例如 0 代表左右 然后按钮也必须有一个 "spacing to nearest neighbor" 到工具栏,例如右边的 8
编辑:请参阅此处添加约束的按钮 http://oi63.tinypic.com/2s7szgi.jpg
显然没有任何方法可以将 splitView 添加到工具栏本身,我怀疑我们在 reeder 中看到的不是标准工具栏。无论如何要得到这个,我做了以下
- 主控制器隐藏标题栏、透明工具栏和全屏视图
- 将高度为 38 的自定义视图添加到每个“源列表(侧边栏)、内容列表(索引列表)和 SplitViewController splitView 项目的默认区域的最顶部。然后将按钮添加到此 splitView
- 这是它在主屏幕上的样子 window
我已经为 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
}
}