如何给 NSOutlineView 一个滚动的平铺背景图像?
How to give an NSOutlineView a tiled background image that scrolls?
我有一个标准NSOutlineView
。我希望它有一个背景图像,垂直平铺,并与轮廓视图单元格一起滚动。
我在我的ViewController中使用以下方法在一定程度上实现了这一点:
class ViewController: NSViewController {
@IBOutlet weak var outlineView: NSOutlineView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if let image = NSImage(named: "tile") {
let color = NSColor.init(patternImage: image)
outlineView.backgroundColor = color
}
}
}
这有效,除非您滚动到视图的顶部或底部(包含滚动视图提供的拉伸)。
我试过将背景图像放在滚动视图上,但它是静态的,不随大纲视图的内容滚动。
我还尝试在视图层次结构中子类化各种对象并覆盖它们的 draw(_ dirtyRect: NSRect)
方法并执行:
self.wantsLayer = true
self.layer?.backgroundColor = ...etc
但也没有成功。
任何人都可以提供任何建议吗?
我最终创建了一个新的自定义 NSView
:
class MyView: NSView {
override func draw(_ dirtyRect: NSRect) {
if let image = NSImage(named: "Tile") {
let color = NSColor.init(patternImage: image)
color.setFill()
dirtyRect.fill()
}
super.draw(dirtyRect)
}
}
然后在我的 ViewController
class 中,我添加了一个自定义视图的实例,并使用自动布局约束将新视图固定到我的 outlineView 的剪辑视图中,从它上方 2000 点开始,到下方 2000 点结束.这意味着无论您过度滚动到拉伸区域多远,您仍然会看到平铺背景。
class MyViewController: NSViewController {
@IBOutlet weak var outlineView: NSOutlineView!
override func viewDidLoad() {
super.viewDidLoad()
guard let clipView = self.outlineView.superview else { return }
let newView = MyView(frame: .zero) // Frame is set by autolayout below.
newView.translatesAutoresizingMaskIntoConstraints = false
clipView.addSubview(newView, positioned: .below, relativeTo: self.outlineView)
// Add autolayout constraints to pin the new view to the clipView.
// See https://apple.co/3c6EMcH
newView.leadingAnchor.constraint(equalTo: clipView.leadingAnchor).isActive = true
newView.widthAnchor.constraint(equalTo: clipView.widthAnchor).isActive = true
newView.topAnchor.constraint(equalTo: clipView.topAnchor, constant: -2000).isActive = true
newView.bottomAnchor.constraint(equalTo: clipView.bottomAnchor, constant: 2000).isActive = true
}
}
我已经从上面删除了其他代码,所以希望我已经留下了说明解决方案所需的一切。
我有一个标准NSOutlineView
。我希望它有一个背景图像,垂直平铺,并与轮廓视图单元格一起滚动。
我在我的ViewController中使用以下方法在一定程度上实现了这一点:
class ViewController: NSViewController {
@IBOutlet weak var outlineView: NSOutlineView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if let image = NSImage(named: "tile") {
let color = NSColor.init(patternImage: image)
outlineView.backgroundColor = color
}
}
}
这有效,除非您滚动到视图的顶部或底部(包含滚动视图提供的拉伸)。
我试过将背景图像放在滚动视图上,但它是静态的,不随大纲视图的内容滚动。
我还尝试在视图层次结构中子类化各种对象并覆盖它们的 draw(_ dirtyRect: NSRect)
方法并执行:
self.wantsLayer = true
self.layer?.backgroundColor = ...etc
但也没有成功。
任何人都可以提供任何建议吗?
我最终创建了一个新的自定义 NSView
:
class MyView: NSView {
override func draw(_ dirtyRect: NSRect) {
if let image = NSImage(named: "Tile") {
let color = NSColor.init(patternImage: image)
color.setFill()
dirtyRect.fill()
}
super.draw(dirtyRect)
}
}
然后在我的 ViewController
class 中,我添加了一个自定义视图的实例,并使用自动布局约束将新视图固定到我的 outlineView 的剪辑视图中,从它上方 2000 点开始,到下方 2000 点结束.这意味着无论您过度滚动到拉伸区域多远,您仍然会看到平铺背景。
class MyViewController: NSViewController {
@IBOutlet weak var outlineView: NSOutlineView!
override func viewDidLoad() {
super.viewDidLoad()
guard let clipView = self.outlineView.superview else { return }
let newView = MyView(frame: .zero) // Frame is set by autolayout below.
newView.translatesAutoresizingMaskIntoConstraints = false
clipView.addSubview(newView, positioned: .below, relativeTo: self.outlineView)
// Add autolayout constraints to pin the new view to the clipView.
// See https://apple.co/3c6EMcH
newView.leadingAnchor.constraint(equalTo: clipView.leadingAnchor).isActive = true
newView.widthAnchor.constraint(equalTo: clipView.widthAnchor).isActive = true
newView.topAnchor.constraint(equalTo: clipView.topAnchor, constant: -2000).isActive = true
newView.bottomAnchor.constraint(equalTo: clipView.bottomAnchor, constant: 2000).isActive = true
}
}
我已经从上面删除了其他代码,所以希望我已经留下了说明解决方案所需的一切。