How to handle keyDown in SwiftUI for macOS

Issue #764 Use a custom KeyAwareView that uses an NSView that checks for keyDown method. In case we can’t handle certain keys, call super.keyDown(with: event) import SwiftUI import KeyboardShortcuts struct KeyAwareView: NSViewRepresentable { let onEvent: (Event) -> Void func makeNSView(context: Context) -> NSView { let view = KeyView() view.onEvent = onEvent DispatchQueue.main.async { view.window?.makeFirstResponder(view) } return view } func updateNSView(_ nsView: NSView, context: Context) {} } extension KeyAwareView { enum Event { case upArrow case downArrow case leftArrow case rightArrow case space case delete case cmdC } } private class KeyView: NSView { var onEvent: (KeyAwareView....

January 29, 2021 · 1 min · Khoa Pham

How to extend custom View in SwiftUI

Issue #763 I usually break down a big struct into smaller views and extensions. For example I have a ClipboardCell that has a lot of onReceive so I want to move these to another component. One way to do that is to extend ClipboardCell struct ClipboardCell: View { let isSelected: Bool @State var showsPreview: Bool @State var showsViewRaw: Bool let onCopy: () -> Void let onDelete: () -> Void } extension ClipboardCell { func onReceiveKeyboard() -> some View { self....

January 28, 2021 · 3 min · Khoa Pham

How to use Sparkle for macOS app

Issue #762 Install Sparkle For now, the latest stable version is 1.24.0 which supports CocoaPods OK, but still, have issues with SPM. Support non sandboxed apps Version 2.0.0 is in beta and supports sandboxed apps To install, use CocoaPods platform :osx, '11.0' target 'MyApp' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! pod 'Sparkle' end Sign In your target, choose Signing & Capability tab, change Signing Certificate from Locally to Development for code sign to work for embedded frameworks...

January 26, 2021 · 2 min · Khoa Pham

How to use ScrollViewReader in SwiftUI

Issue #761 Explicitly specify id ScrollView { ScrollViewReader { proxy in LazyVStack(spacing: 10) { ForEach(items) { item in Cell(item: item) .id(item.id) } } .padding() .onReceiveKeyboard(onNext: { onNext() if let item = selectedItem { proxy.scrollTo(item.id, anchor: .center) } }, onPrevious: { onPrevious() if let item = selectedItem { proxy.scrollTo(item.id, anchor: .center) } }) } } I usually extract ScrollViewReader into a helper function that use onChange to react to state changes...

January 21, 2021 · 1 min · Khoa Pham

How to handle keyDown in NSResponder

Issue #760 import AppKit import Omnia class MyWindow: NSWindow { override func keyDown(with event: NSEvent) { super.keyDown(with: event) if isKey(NSDeleteCharacter, event: event) { NotificationCenter.default.post(Notification(name: .didKeyboardDeleteItem)) } else if isKey(NSUpArrowFunctionKey, event: event) { print("up") } else if isKey(NSDownArrowFunctionKey, event: event) { print("down") } else if isKey(NSLeftArrowFunctionKey, event: event) { print("left") } else if isKey(NSRightArrowFunctionKey, event: event) { print("right") } } private func isKey(_ key: Int, event: NSEvent) -> Bool { if let scalar = UnicodeScalar(key) { return event....

January 21, 2021 · 2 min · Khoa Pham

How to handle NSSearchToolbarItem in macOS 11

Issue #758 extension NSToolbarItem.Identifier { static let searchItem: NSToolbarItem.Identifier = NSToolbarItem.Identifier("SearchItem") } let searchItem = NSSearchToolbarItem(itemIdentifier: .searchItem) extension AppDelegate: NSToolbarDelegate { func toolbar( _ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool ) -> NSToolbarItem? { switch itemIdentifier { case .searchItem: searchItem.searchField.delegate = self return searchItem } } extension AppDelegate: NSSearchFieldDelegate { func control( _ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector ) -> Bool { if (commandSelector == #selector(NSResponder.insertNewline(_:))) { print("enter") return true } return false } } ...

January 21, 2021 · 1 min · Khoa Pham

How to do launch at login for macOS apps

Issue #757 Use SMLoginItemSetEnabled from Service Management framework Use a helper background app that checks and invokes our main application Copy our helper app into Library/LoginItems helper_dir="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems" final class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ notification: Notification) { let bundleId = Bundle.main.bundleIdentifier! // TODO:Make this more strict by only replacing at the end let mainBundleId = bundleId.replacingOccurrences(of: "-LaunchAtLoginHelper", with: "") // Ensure the app is not already running guard NSRunningApplication....

January 20, 2021 · 1 min · Khoa Pham

How to fix overlapped navigation titles in SwiftUI

Issue #756 extension NavigationLink { func fixOverlap() -> AnyView { if UIDevice.current.userInterfaceIdiom == .phone { return self.isDetailLink(false).erase() } else { return self.erase() } } } Read more https://www.dabblingbadger.com/blog/2020/12/11/a-quick-fix-for-overlapping-navigation-titles-in-swiftui As far as I can tell, this bug only shows up if you: 1) have the navigation title displayMode of a destination view set to .large and 2) have added items to the navigation bar using the .navigationBarItems modifier....

January 20, 2021 · 1 min · Khoa Pham

How to use NSWindow style and NSToolbar in AppKit

Issue #755 Read more https://github.com/martinlexow/SwiftUIWindowStyles https://github.com/lukakerr/NSWindowStyles https://github.com/marioaguzman/toolbar Updated at 2021-01-21 12:46:04...

January 20, 2021 · 1 min · Khoa Pham

How to use NSSplitViewController in AppKit

Issue #754 Read more https://github.com/KevinGutowski/SplitConfigurations Updated at 2021-01-20 05:30:46...

January 20, 2021 · 1 min · Khoa Pham