I made a simple project in Xcode to track the position of a touch event on a trackpad. I created a Custom View instance on my MainWindowController.xib for the class TrackpadController:
class TrackpadController: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect);
self.acceptsTouchEvents = true
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func touchesBeganWithEvent(event: NSEvent) {
let touches = event.touchesMatchingPhase(.Began, inView: nil)
for touch in touches {
let touchPosition = touch.normalizedPosition
Swift.print(touchPosition)
}
}
}
The coordinates are printed in the console, but only if the cursor is over the view. I would like to be able to track the position on the trackpad when the app isn't focused. Any idea in how to get this would be great. Thanks.
Related
Is there a way to use SceneKit's SceneView to render it into the ScreenSaverView. I tried couple of things, but can't seem to figure this out.
I know putting 3D graphics into screensaver is not a good idea, just making this for fun.
Here's the code I have right now:
import ScreenSaver
import Foundation
import SceneKit
class MainView: ScreenSaverView {
var sceneView: SCNView
// MARK: - Initialization
override init?(frame: NSRect, isPreview: Bool) {
sceneView = SCNView(frame: frame)
super.init(frame: frame, isPreview: isPreview)
sceneView.scene = SCNScene(named: "monkey")!
self.addSubview(sceneView)
}
#available(*, unavailable)
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Lifecycle
override func draw(_ rect: NSRect) {
// Draw a single frame in this function
self.sceneView.draw(bounds)
}
override func animateOneFrame() {
super.animateOneFrame()
// Update the "state" of the screensaver in this function
setNeedsDisplay(bounds)
}
}
I have instantiated and initialized a subclass of NSDatePicker in AppDelegate -> applicationDidFinishLaunching and overrode mouseDown(with event: NSEvent)in the datePicker subclass. When I press the mouse button in the datePicker and break in its overridden mouseDown func the instance is not the one I instantiated in applicationDidFinishLaunching and so is not initialized.
I've tried creating the instance at different entry points thinking it might be a timing thing but I've gotten nowhere. I'm out of ideas and feeling a little feeble. Any Help?
The datePicker:
import Cocoa
class AlarmIVDatePicker: NSDatePicker {
var viewController: ViewController!
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
return true
}
override func mouseDown(with event: NSEvent) {
let stop = 0
}
}
The ViewController:
class ViewController: NSViewController, NSWindowDelegate{
var alarmIVDatePicker: AlarmIVDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
alarmIVDatePicker = AlarmIVDatePicker()
alarmIVDatePicker.viewController = self
}
I expected I could access the values I had set but the instance is not the one I created and all the values are nil
Okay. Here's what you can do to track this down. Add this code to your AlarmIVDatePicker class:
override init(frame frameRect: NSRect) {
Swift.print("AlarmIVDatePicker being called here")
super.init(frame: frameRect)
}
convenience init() {
self.init(frame: .zero)
}
required init?(coder: NSCoder) {
Swift.print("hey, you DID drop this into a storyboard or XIB file!")
super.init(coder: coder)
}
If you set breakpoints inside these init methods, you'll catch when and where they are being called where you did not expect.
I have problems in getting my custom NSSlider control updated live within Xcode's Interface Builder.
I have implemented #IBDesignable and prepareForInterfaceBuilder as shown in many other posts and tutorials. My little test just removes the knob from the slider control.
Here is the code I am using at the moment:
import Cocoa
#IBDesignable
class ColorSlider2: NSSlider {
override func setNeedsDisplay(_ invalidRect: NSRect) {
super.setNeedsDisplay(invalidRect)
}
override func awakeFromNib() {
super.awakeFromNib()
setupView()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
private func setupView() {
if ((self.cell?.isKind(of: ColorSlider2Cell.self)) == false) {
let cell = ColorSlider2Cell()
self.cell = cell
}
self.alphaValue = 0.5
self.floatValue = 0.4
}
}
class ColorSlider2Cell: NSSliderCell {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init() {
super.init()
}
override func drawKnob(_ knobRect: NSRect) {
return
}
}
The preview in Interface Builder is neither removing the knob nor updating the floatValue:
Do you have any idea why this is the case?
How to observer in UITexFiled sub class ,if current textField is started Ending or Ended Editing in same class .
if I'll write self.delegate = self then my ViewController UITextField method will not called .
I want to make a UITexFiled SubClass when every editing is started then I'll scale up the textFiled ,and when editing is done then UITexField will be back to normal size . but I want to handle from my subclass not to write logic every UITexFeildDelegate in all ViewController Please help me .
You can add targets for the specific events
class MyTextField: UITextField {
override init(frame: CGRect) {
super.init(frame:frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
self.addTarget(self, action: #selector(didBegin), for: .editingDidBegin)
self.addTarget(self, action: #selector(didEnd), for: .editingDidEnd)
}
#objc func didBegin() {
}
#objc func didEnd() {
}
}
In Cocoa Touch, you can disable user interaction of a text view like this:
let textView = UITextView()
textView.isUserInteractionEnabled = false
But in Cocoa, NSTextView has no such easy API to use.
So what's the proper way to disable NSTextView user interaction?
You can disable its' editable by:
textView.isEditable = false
And its' selectable by:
textView.isSelectable = false
However, when you disable both of them. This textView still will intercept Mouse-down event, which is different from isUserInteractionEnabled .
So, for now, to enable click-through, my solution is subclassing a NSTextView and override its' hitTest:
class TextView: NSTextView {
override func hitTest(_ point: NSPoint) -> NSView? {
return nil
}
}
An encapsulated way is here
class StaticTextView: NSTextView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
override init(frame frameRect: NSRect, textContainer container: NSTextContainer?) {
super.init(frame: frameRect, textContainer: container)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func hitTest(_ point: NSPoint) -> NSView? {
return nil
}
}