Difference between revisions of "Swift Snippets"

From PeformIQ Upgrade
Jump to navigation Jump to search
(Created page with " * https://stackoverflow.com/questions/59635971/show-nsmenu-only-on-nsstatusbarbutton-right-click <pre> func applicationDidFinishLaunching(_ aNotification: Notification) { statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) statusItem.button?.action = #selector(onClick) statusItem.button?.sendAction(on: [.leftMouseUp, .rightMouseUp]) menu = NSMenu() menu.addItem(NSMenuItem(title: "Quit", ac...")
 
 
(2 intermediate revisions by the same user not shown)
Line 35: Line 35:
</pre>
</pre>


OK Got exercise working but status bar truncates length of time.  Setting a length of 53 seems to be th e max - any larger an the display fails.  Have not worked out how to user a smaller font so it will not overflow the space available.


=Mouse Location=
From 2015...
* https://stackoverflow.com/questions/31931403/getting-mouse-coordinates-in-swift
If you would like to monitor events on any window when your app is active, you can add a LocalMonitorForEvents matching mouseMoved mask and if it is not active a GlobalMonitorForEvents. Note that you need set to your window property acceptsMouseMovedEvents to true
</pre>
import Cocoa
class ViewController: NSViewController {
    lazy var window: NSWindow = self.view.window!
    var mouseLocation: NSPoint { NSEvent.mouseLocation }
    var location: NSPoint { window.mouseLocationOutsideOfEventStream }
    override func viewDidLoad() {
        super.viewDidLoad()
        NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) {
            print("mouseLocation:", String(format: "%.1f, %.1f", self.mouseLocation.x, self.mouseLocation.y))
            print("windowLocation:", String(format: "%.1f, %.1f", self.location.x, self.location.y))
            return $0
        }
        NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved]) { _ in
            print(String(format: "%.0f, %.0f", self.mouseLocation.x, self.mouseLocation.y))
        }
    }
    override func viewWillAppear() {
        super.viewWillAppear()
        window.acceptsMouseMovedEvents = true
    }
}
</pre>
You can get the current mouse location in this way:
Declare this in your view controller class:
<pre>
var mouseLocation: NSPoint? { self.view.window?.mouseLocationOutsideOfEventStream }
</pre>
Then, you can get the current mouse location and convert in your desired view coordinates:
<pre>
if let currentMouseLocation = self.mouseLocation{
    let pointInTargetView = self.**targetView**.convert(currentMouseLocation, from: self.view)
}
</pre>
=Get Coordinates of TextField or any View in SwiftUI=
Here is a demo of how specific view coordinates can be read (see helpful comments inline)
<pre>
struct DemoReadViewOrigin: View {
    @State private var someNumber1 = "1000"
    @State private var someNumber2 = "2000"
    //bunch more
    @State private var enteredNumber = "Some Text at the Top"
    @State var value: CGFloat = 0
    var body: some View {
        ScrollView {
            VStack {
                Spacer()
                Text("\(enteredNumber)")
                Spacer()
                Group { //1
                    TextField("Placeholder", text: $someNumber1)
                        .keyboardType(.default)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .background(GeometryReader { gp -> Color in
                            let rect = gp.frame(in: .named("OuterV")) // < in specific container
                            // let rect = gp.frame(in: .global) // < in window
                            // let rect = gp.frame(in: .local) // < own bounds
                            print("Origin: \(rect.origin)")
                            return Color.clear
                        })
                        //this does not work
                        .onTapGesture {
                        }
                    TextField("Placeholder", text: $someNumber2)
                        .keyboardType(.default)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
              }//group 1
              //bunch more
                Button(action: {
                    self.enteredNumber = self.someNumber1
                    self.someNumber1 = ""
//                    UIApplication.shared.endEditing()
                }) {
                    Text("Submit")
                }
                .padding(.bottom, 50)
            }//outer v
                .coordinateSpace(name: "OuterV") // << declare coord space
                .padding(.horizontal, 16)
                .padding(.top, 44)
        }//Scrollview or Form
//        .modifier(AdaptsToSoftwareKeyboard())
    }
}
</pre>


[[Category:Development]]
[[Category:Development]]
[[Category:Swift]]
[[Category:Swift]]

Latest revision as of 10:35, 11 December 2022

func applicationDidFinishLaunching(_ aNotification: Notification) {
        statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        statusItem.button?.action = #selector(onClick)
        statusItem.button?.sendAction(on: [.leftMouseUp, .rightMouseUp])
        
        menu = NSMenu()
        menu.addItem(NSMenuItem(title: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
        menu.delegate = self
        
    }
    
    @objc func onClick(sender: NSStatusItem) {
        
        let event = NSApp.currentEvent!
       
        if event.type == NSEvent.EventType.rightMouseUp {
            // right click, show quit menu
            statusItem.menu = menu;
            menu.popUp(positioning: nil, 
                at: NSPoint(x: 0, y: statusItem.statusBar!.thickness),
                in: statusItem.button)
        } else {
           // main click 
        }
    }
    @objc func menuDidClose(_ menu: NSMenu) {
        // remove menu when closed so we can override left click behavior
        statusItem.menu = nil
    }

OK Got exercise working but status bar truncates length of time. Setting a length of 53 seems to be th e max - any larger an the display fails. Have not worked out how to user a smaller font so it will not overflow the space available.

Mouse Location

From 2015...

If you would like to monitor events on any window when your app is active, you can add a LocalMonitorForEvents matching mouseMoved mask and if it is not active a GlobalMonitorForEvents. Note that you need set to your window property acceptsMouseMovedEvents to true

import Cocoa

class ViewController: NSViewController {

   lazy var window: NSWindow = self.view.window!
   var mouseLocation: NSPoint { NSEvent.mouseLocation }
   var location: NSPoint { window.mouseLocationOutsideOfEventStream }
   override func viewDidLoad() {
       super.viewDidLoad()
       NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) {
           print("mouseLocation:", String(format: "%.1f, %.1f", self.mouseLocation.x, self.mouseLocation.y))
           print("windowLocation:", String(format: "%.1f, %.1f", self.location.x, self.location.y))
           return $0
       }
       NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved]) { _ in
           print(String(format: "%.0f, %.0f", self.mouseLocation.x, self.mouseLocation.y))
       }
   }
   override func viewWillAppear() {
       super.viewWillAppear()
       window.acceptsMouseMovedEvents = true
   }

}

You can get the current mouse location in this way:

Declare this in your view controller class:

var mouseLocation: NSPoint? { self.view.window?.mouseLocationOutsideOfEventStream }

Then, you can get the current mouse location and convert in your desired view coordinates:

if let currentMouseLocation = self.mouseLocation{

     let pointInTargetView = self.**targetView**.convert(currentMouseLocation, from: self.view)

}


Get Coordinates of TextField or any View in SwiftUI

Here is a demo of how specific view coordinates can be read (see helpful comments inline)

struct DemoReadViewOrigin: View {

    @State private var someNumber1 = "1000"
    @State private var someNumber2 = "2000"
    //bunch more

    @State private var enteredNumber = "Some Text at the Top"
    @State var value: CGFloat = 0

    var body: some View {
        ScrollView {
            VStack {
                Spacer()
                Text("\(enteredNumber)")
                Spacer()

                Group { //1
                    TextField("Placeholder", text: $someNumber1)
                        .keyboardType(.default)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .background(GeometryReader { gp -> Color in
                            let rect = gp.frame(in: .named("OuterV")) // < in specific container
                            // let rect = gp.frame(in: .global) // < in window
                            // let rect = gp.frame(in: .local) // < own bounds
                            print("Origin: \(rect.origin)")
                            return Color.clear
                        })

                        //this does not work
                        .onTapGesture {
                        }

                    TextField("Placeholder", text: $someNumber2)
                        .keyboardType(.default)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
               }//group 1

               //bunch more

                Button(action: {
                    self.enteredNumber = self.someNumber1
                    self.someNumber1 = ""
//                    UIApplication.shared.endEditing()
                }) {
                    Text("Submit")
                }
                .padding(.bottom, 50)

            }//outer v
                .coordinateSpace(name: "OuterV") // << declare coord space
                .padding(.horizontal, 16)
                .padding(.top, 44)

        }//Scrollview or Form
//        .modifier(AdaptsToSoftwareKeyboard())
    }
}