How to use TabView with enum in SwiftUI

Issue #599 Specify tag enum Authentication: Int, Codable { case key case certificate } TabView(selection: $authentication) { KeyAuthenticationView() .tabItem { Text("🔑 Key") } .tag(Authentication.key) CertificateAuthenticationView() .tabItem { Text("📰 Certificate") } .tag(Authentication.certificate) }

February 11, 2020 · 1 min · Khoa Pham

How to build SwiftUI style UICollectionView data source in Swift

Issue #598 It’s hard to see any iOS app which don’t use UITableView or UICollectionView, as they are the basic and important foundation to represent data. UICollectionView is very basic to use, yet a bit tedious for common use cases, but if we abstract over it, then it becomes super hard to customize. Every app is unique, and any attempt to wrap around UICollectionView will fail horribly. A sensable approach for a good abstraction is to make it super easy for normal cases, and easy to customize for advanced scenarios....

February 9, 2020 · 4 min · Khoa Pham

How to make round border in SwiftUI

Issue #597 TextView(font: R.font.text!, lineCount: nil, text: $text, isFocus: $isFocus) .padding(8) .background(R.color.inputBackground) .cornerRadius(10) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(isFocus ? R.color.inputBorderFocus : Color.clear, lineWidth: 1) )

February 5, 2020 · 1 min · Khoa Pham

How to mock in Swift

Issue #596 Unavailable init UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in let status: UNAuthorizationStatus = .authorized settings.setValue(status.rawValue, forKey: "authorizationStatus") completionHandler(settings) })

February 4, 2020 · 1 min · Khoa Pham

How to change background color in List in SwiftUI for macOS

Issue #595 SwiftUI uses ListCoreScrollView and ListCoreClipView under the hood. For now the workaround, is to avoid using List List { ForEach } use VStack { ForEach } Updated at 2020-08-14 07:26:27

February 4, 2020 · 1 min · Khoa Pham

How to add drag and drop in SwiftUI

Issue #594 In some case, we should not use base type like UTType.text but to be more specific like UTType.utf8PlainText import UniformTypeIdentifiers var dropTypes: [UTType] { [ .fileURL, .url, .utf8PlainText, .text ] } func handleDrop(info: DropInfo) -> Bool { for provider in info.itemProviders(for: dropTypes) { for type in dropTypes { provider.loadDataRepresentation(forTypeIdentifier: type.identifier) { data, _ in guard let data = data, let string = String(data: data, encoding: .utf8) else { return } DispatchQueue....

February 4, 2020 · 2 min · Khoa Pham

How to make radio button group in SwiftUI

Issue #592 Use picker with Radio style Hard to customize Picker(selection: Binding<Bool>.constant(true), label: EmptyView()) { Text("Production").tag(0) Text("Sandbox").tag(1) }.pickerStyle(RadioGroupPickerStyle()) Use custom view Use contentShape to make whole button tappable. Make custom Binding for our enum struct EnvironmentView: View { @Binding var input: Input var body: some View { VStack(alignment: .leading) { RadioButton(text: "Production", isOn: binding(for: .production)) RadioButton(text: "Sandbox", isOn: binding(for: .sandbox)) } } private func binding(for environment: Input.Environment) -> Binding<Bool> { Binding<Bool>( get: { self....

February 1, 2020 · 1 min · Khoa Pham

How to set font to NSTextField in macOS

Issue #591 Use NSTextView instead

January 29, 2020 · 1 min · Khoa Pham

How to make borderless material NSTextField in SwiftUI for macOS

Issue #590 Use custom NSTextField as it is hard to customize TextFieldStyle import SwiftUI struct MaterialTextField: View { let placeholder: String @Binding var text: String @State var isFocus: Bool = false var body: some View { VStack(alignment: .leading, spacing: 0) { BorderlessTextField(placeholder: placeholder, text: $text, isFocus: $isFocus) .frame(maxHeight: 40) Rectangle() .foregroundColor(isFocus ? R.color.separatorFocus : R.color.separator) .frame(height: isFocus ? 2 : 1) } } } class FocusAwareTextField: NSTextField { var onFocusChange: (Bool) -> Void = { _ in } override func becomeFirstResponder() -> Bool { let textView = window?...

January 29, 2020 · 2 min · Khoa Pham

How to make focusable NSTextField in macOS

Issue #589 Use onTapGesture import SwiftUI struct MyTextField: View { @Binding var text: String let placeholder: String @State private var isFocus: Bool = false var body: some View { FocusTextField(text: $text, placeholder: placeholder, isFocus: $isFocus) .padding() .cornerRadius(4) .overlay( RoundedRectangle(cornerRadius: 4) .stroke(isFocus ? Color.accentColor: Color.separator) ) .onTapGesture { isFocus = true } } } private struct FocusTextField: NSViewRepresentable { @Binding var text: String let placeholder: String @Binding var isFocus: Bool func makeNSView(context: Context) -> NSTextField { let tf = NSTextField() tf....

January 29, 2020 · 2 min · Khoa Pham

How to observe focus event of NSTextField in macOS

Issue #589 becomeFirstResponder class FocusAwareTextField: NSTextField { var onFocusChange: (Bool) -> Void = { _ in } override func becomeFirstResponder() -> Bool { let textView = window?.fieldEditor(true, for: nil) as? NSTextView textView?.insertionPointColor = R.nsColor.action onFocusChange(true) return super.becomeFirstResponder() } } textField.delegate // NSTextFieldDelegate func controlTextDidEndEditing(_ obj: Notification) { onFocusChange(false) } NSTextField and NSText https://stackoverflow.com/questions/25692122/how-to-detect-when-nstextfield-has-the-focus-or-is-its-content-selected-cocoa When you clicked on search field, search field become first responder once, but NSText will be prepared sometime somewhere later, and the focus will be moved to the NSText....

January 29, 2020 · 1 min · Khoa Pham

How to change caret color of NSTextField in macOS

Issue #588 class FocusAwareTextField: NSTextField { var onFocus: () -> Void = {} var onUnfocus: () -> Void = {} override func becomeFirstResponder() -> Bool { onFocus() let textView = window?.fieldEditor(true, for: nil) as? NSTextView textView?.insertionPointColor = R.nsColor.action return super.becomeFirstResponder() } override func resignFirstResponder() -> Bool { onUnfocus() return super.resignFirstResponder() } }

January 29, 2020 · 1 min · Khoa Pham

How to make TextView in SwiftUI for macOS

Issue #587 Use NSTextVIew From https://github.com/twostraws/ControlRoom/blob/main/ControlRoom/NSViewWrappers/TextView.swift import SwiftUI /// A wrapper around NSTextView so we can get multiline text editing in SwiftUI. struct TextView: NSViewRepresentable { @Binding private var text: String private let isEditable: Bool init(text: Binding<String>, isEditable: Bool = true) { _text = text self.isEditable = isEditable } init(text: String) { self.init(text: Binding<String>.constant(text), isEditable: false) } func makeNSView(context: Context) -> NSScrollView { let text = NSTextView() text.backgroundColor = isEditable ?...

January 29, 2020 · 2 min · Khoa Pham

How to use custom font in SwiftUI

Issue #586 In macOS Add fonts to target. In Info.plist, just need to specify font locations, most of the time they are at Resources folder ATSApplicationFontsPath (String - macOS) identifies the location of a font file or directory of fonts in the bundle’s Resources directory. If present, macOS activates the fonts at the specified path for use by the bundled app. The fonts are activated only for the bundled app and not for the system as a whole....

January 28, 2020 · 2 min · Khoa Pham

How to test drag and drop in UITests

Issue #583 In UITests, we can use press from XCUIElement to test drag and drop let fromCat = app.buttons["cat1"].firstMatch let toCat = app.buttons["cat2"] let fromCoordinate = fromCat.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)) let toCoordinate = toCat.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: -0.5)) fromCoordinate.press(forDuration: 1, thenDragTo: toCoordinate) and then take screenshot let screenshot = XCUIScreen.main.screenshot() let attachment = XCTAttachment(screenshot: screenshot) attachment.lifetime = .keepAlways attachment.name = name add(attachment) Screenshot capturing happens after the action, so it may be too late....

January 23, 2020 · 1 min · Khoa Pham

How to set corner radius in iOS

Issue #582 Use View Debugging Run on device, Xcode -> Debug -> View debugging -> Rendering -> Color blended layer On Simulator -> Debug -> Color Blended Layer Corner radius https://twitter.com/timoliverau/status/1135999854176395264 Okay. Talked to a Core Animation engineer again: cornerRadius was deliberately improved in Metal so it could be used everywhere. Using a bitmap is WAY heavier in terms of memory and performance. CALayer maskLayer is still heavy....

January 22, 2020 · 4 min · Khoa Pham

How to deal with Swift slow compile time

Issue #581 Read more https://engineering.circle.com/swift-compiler-performance-tips-and-tricks-e86a53a5b42a https://swiftrocks.com/reducing-ios-build-times-by-using-interface-targets.html

January 21, 2020 · 1 min · Khoa Pham

How to work with SceneDelegate in iOS 12

Issue #580 Events open url https://stackoverflow.com/questions/58624786/method-applicationopenurloptions-is-not-called Implement scene(_:openURLContexts:) in your scene delegate. If the URL launches your app, you will get scene(_:willConnectTo:options:) instead and it’s in the options. life cycle https://stackoverflow.com/questions/56508764/app-delegate-methods-arent-being-called-in-ios-13 Here’s how it works: If you have an “Application Scene Manifest” in your Info.plist and your app delegate has a configurationForConnectingSceneSession method, the UIApplication won’t send background and foreground lifecycle messages to your app delegate....

January 20, 2020 · 2 min · Khoa Pham

How to handle radio group for NSButton

Issue #579 Use same action, or we can roll our own implementation An NSButton configured as a radio button (with the -buttonType set to NSRadioButton), will now operate in a radio button group for applications linked on 10.8 and later. To have the button work in a radio group, use the same -action for each NSButton instance, and have the same superview for each button. When these conditions are met, checking one button (by changing the -state to 1), will uncheck all other buttons (by setting their -state to 0)....

January 17, 2020 · 1 min · Khoa Pham

How to specify locale in Swift

Issue #578 Locale Read Language and Locale IDs zh-Hans_HK [language designator]-[script designator]_[region designator] Language IDs A language ID identifies a language used in many regions, a dialect used in a specific region, or a script used in multiple regions. To specify a language used in many regions, use a language designator by itself. To specify a specific dialect, use a hyphen to combine a language designator with a region designator....

January 14, 2020 · 2 min · Khoa Pham