How to suppress selector warning in Swift

Issue #777 Sometimes we need to use dynamic selector and that triggers warning in Swift Selector("updateWithCount:") // Use '#selector' instead of explicitly constructing a 'Selector' In ObjC we can use clang macro to suppress, like below #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" - (void) deprecated_objc_method_override { } #pragma clang diagnostic pop But in Swift, we can just use a dummy NSObject that has the needed methods, like...

February 18, 2021 · 1 min · Khoa Pham

How to make simple search bar in SwiftUI

Issue #776 We need to use a custom Binding to trigger onChange as onEditingChanged is only called when the user selects the textField, and onCommit is only called when return or done button on keyboard is tapped. import UIKit import SwiftUI import EasySwiftUI struct SearchBar: View { @Binding var searchText: String let onChange: () -> Void @State private var showsCancelButton: Bool = false var body: some View { return HStack { textField cancelButton } } private var searchTextBinding: Binding<String> { Binding<String>(get: { searchText }, set: { newValue in DispatchQueue....

February 17, 2021 · 1 min · Khoa Pham

How to fix share and action extension not showing up in iOS 14

Issue #775 My share sheet and action extension not showing up in iOS 14, built-in Xcode 12.3. The solution is to restart test device, and it shows up again. Also make sure your extension targets have the same version and build number, and same deployment target <dict> <key>NSExtensionAttributes</key> <dict> <key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationDictionaryVersion</key> <integer>2</integer> <key>NSExtensionActivationSupportsText</key> <true/> <key>NSExtensionActivationSupportsWebURLWithMaxCount</key> <integer>1</integer> <key>NSExtensionActivationSupportsWebPageWithMaxCount</key> <integer>1</integer> </dict> <key>NSExtensionJavaScriptPreprocessingFile</key> <string>MyPreprocessor</string> <key>NSExtensionActivationUsesStrictMatching</key> <integer>2</integer> </dict> Updated at 2021-02-17 20:49:49...

February 17, 2021 · 1 min · Khoa Pham

How to add home screen quick action in SwiftUI

Issue #774 Start by defining your quick actions. You can use UIApplicationShortcutIcon(type:) for predefined icons, or use UIApplicationShortcutIcon(systemImageName:) for SFSymbol enum QuickAction: String { case readPasteboard case clear var shortcutItem: UIApplicationShortcutItem { switch self { case .readPasteboard: return UIApplicationShortcutItem( type: rawValue, localizedTitle: "Read Pasteboard", localizedSubtitle: "", icon: UIApplicationShortcutIcon(type: .add), userInfo: nil ) case .clear: return UIApplicationShortcutItem( type: rawValue, localizedTitle: "Clear Pasteboard", localizedSubtitle: "", icon: UIApplicationShortcutIcon(systemImageName: SFSymbol.wind.rawValue), userInfo: nil ) } } } Add a service to store selected quick action....

February 10, 2021 · 2 min · Khoa Pham

How to use EquatableView in SwiftUI

Issue #773 From John Harper ’s tweet SwiftUI assumes any Equatable.== is a true equality check, so for POD views it compares each field directly instead (via reflection). For non-POD views it prefers the view’s == but falls back to its own field compare if no ==. EqView is a way to force the use of ==. When it does the per-field comparison the same rules are applied recursively to each field (to choose direct comparison or == if defined)....

February 8, 2021 · 1 min · Khoa Pham

How to add new property in Codable struct in SwiftUI

Issue #772 I use Codable structs in my apps for preferences, and bind them to SwiftUI views. If we add new properties to existing Codable, it can’t decode with old saved json as we require new properties. We can either do cutom decoding with container, but this can result in lots more code and mistakes if we have many properties inside our struct. The quick workaround is to declare new properties as optional, and use a computed property to wrap that....

February 8, 2021 · 1 min · Khoa Pham

How to show close button in NSTextField in AppKit

Issue #771 Use NSSearchField instead...

February 6, 2021 · 1 min · Khoa Pham

How to handle escape in NSTextField in SwiftUI

Issue #770 Handle cancelOperation somewhere up in responder chain class MyWindow: NSWindow { let keyHandler = KeyHandler() override func cancelOperation(_ sender: Any?) { super.cancelOperation(sender) keyHandler.onEvent(.esc) } } ...

February 6, 2021 · 1 min · Khoa Pham

How to fit ScrollView to content in SwiftUI

Issue #769 If we place ScrollView inside HStack or VStack, it takes all remaining space. To fit ScrollView to its content, we need to get its content size and constrain ScrollView size. Use a GeometryReader as Scrollview content background, and get the local frame import SwiftUI struct HSearchBar: View { @State private var scrollViewContentSize: CGSize = .zero var body: some View { HStack { searchButton ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 12) { ForEach(store....

February 6, 2021 · 1 min · Khoa Pham

How to show modal window in SwiftUI for macOS

Issue #768 Use custom NSWindow, set level in becomeKey and call NSApp.runModal to show modal final class ModalWindow: NSWindow { override func becomeKey() { super.becomeKey() level = .statusBar } override func close() { super.close() NSApp.stopModal() } } let window = ModalWindow( contentRect: .zero, styleMask: [.titled, .closable], backing: .buffered, defer: false ) window.titlebarAppearsTransparent = true window.title = "Manage collections" window.center() window.isReleasedWhenClosed = false self.window = window let view = CollectionSettingsView(store: Store.shared) ....

February 3, 2021 · 1 min · Khoa Pham