Skip to content

Instantly share code, notes, and snippets.

@Pyroh
Last active April 27, 2022 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pyroh/f066b3096ecceb582560ef403c9bf0f7 to your computer and use it in GitHub Desktop.
Save Pyroh/f066b3096ecceb582560ef403c9bf0f7 to your computer and use it in GitHub Desktop.
import Cocoa
import SwiftUI
/// Preview tool
struct ViewRepresentable<V: NSView>: NSViewRepresentable {
let provider: () -> V
func makeNSView(context: Context) -> V { provider() }
func updateNSView(_ nsView: V, context: Context) { }
}
struct ViewControllerRepresentable<C: NSViewController>: NSViewControllerRepresentable {
let provider: () -> C
func makeNSViewController(context: Context) -> C { provider() }
func updateNSViewController(_ nsViewController: C, context: Context) { }
}
struct Preview<T: NSResponder, R: View>: View {
let provider: R
var body: some View { provider }
}
extension Preview where T: NSView, R == ViewRepresentable<T> {
init(_ provider: @escaping () -> T) {
self.provider = ViewRepresentable(provider: provider)
}
init(_ view: T) {
self.provider = ViewRepresentable(provider: { view })
}
}
extension Preview where T: NSViewController, R == ViewControllerRepresentable<T> {
init(_ provider: @escaping () -> T) {
self.provider = ViewControllerRepresentable(provider: provider)
}
init(_ controller: T) {
self.provider = ViewControllerRepresentable(provider: { controller })
}
}
/// End of preview tool
class DrawOnView: NSView {
var alternateState: Bool = false {
didSet { needsDisplay = true }
}
override func draw(_ rect: CGRect) {
let leadingPoint = CGPoint(x: bounds.minX, y: alternateState ? bounds.minY : bounds.maxY)
let trailingPoint = CGPoint(x: bounds.maxX, y: alternateState ? bounds.maxY : bounds.minY)
let context = NSGraphicsContext.current?.cgContext
context?.setLineWidth(2.0)
context?.setStrokeColor(NSColor.blue.cgColor)
context?.move(to: leadingPoint)
context?.addLine(to: trailingPoint)
context?.strokePath()
}
}
class DrawOnViewController: NSViewController {
var drawOnView: DrawOnView
init() {
self.drawOnView = .init()
super.init(nibName: nil, bundle: nil)
self.wrapAndInstall()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBAction func toggleState(_ sender: Any?) {
drawOnView.alternateState.toggle()
}
private func wrapAndInstall() {
let button = NSButton(title: "Toggle", target: self, action: #selector(toggleState))
button.setContentHuggingPriority(.defaultHigh, for: .horizontal)
let stack = NSStackView(views: [button, drawOnView])
stack.orientation = .vertical
stack.spacing = 8
view = stack
}
}
struct SampleView_Previews: PreviewProvider {
static var previews: some View {
Preview(DrawOnViewController())
.frame(width: 120, height: 140)
.padding()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment