How to simplify communication patterns with closure in Swift

Issue #744 As someone who builds lots of apps, I try to find quick ways to do things. One of them is to avoid repetitive and cumbersome APIs. That’s why I built Anchors to make Auto Layout more convenient, Omnia to add missing extensions. The next thing in the itchy list is the many ways to communicate among objects in iOS and macOS development that can be very annoying sometimes....

January 6, 2021 · 11 min · 2333 words · Khoa

How to use Apple keyboard key symbols

Issue #743 •  = Apple logo • ⌘ = Command • ⇧ = Shift • ⌫ = Backspace/Delete • ⇪ = Caps lock • ⌥ = Option/Alt • ⌃ = Control • ⎋ = Escape • ←↑→↓ = Arrow Keys • ↩ = Return

January 5, 2021 · 1 min · 45 words · Khoa

How to make Auto Layout more convenient in iOS

Issue #742 Auto Layout has been around since macOS 10.7 and iOS 6.0 as a nicer way to do layouts over the old resizing masks. Besides some rare cases when we need to manually specify origins and sizes, Auto Layout is the preferred way to do declarative layouts whether we choose to do UI in code or Storyboard. The Auto Layout APIs have some improvements over the years, there are also some sugar libraries that add easy syntaxes, so more choices for developers....

January 5, 2021 · 18 min · 3711 words · Khoa

How to form product idea

Issue #740 How to gain product ideas? Scratch your own itch. If you don’t have any itch to scratch, stop here. This is awkward. Go travelling. Go exploring the world. The world always has problems and needs solution. Image Build any service, app or website. Along the way you’ll find tons of things you need that and unsolved by existing solutions, and tons of things you can improve upon. Sign up for some paid newsletters to find ideas....

January 4, 2021 · 2 min · 281 words · Khoa

How to join AppStore Small Business Program

Issue #739 New program reduces App Store commission to 15 percent for small businesses earning up to $1 million per year “earning up to $1 million” means proceeds, not sales. This is what we get after Apple’s cut. “up to” means $999.999 “if they earned up to $1 million in proceeds during the previous calendar year”. This means that if $1M is surpassed, the standard rate (30%) kicks in for the rest of the year, and also next year....

January 4, 2021 · 1 min · 179 words · Khoa

How to deep work

Issue #738 Just found out the book Deep Work by Cal Newport and it has some interesting guidelines Here’s a very good summary of the book https://www.youtube.com/watch?v=gTaJhjQHcf8&ab_channel=ProductivityGame Put a boundary on distraction. Allow yourself to be distracted at predefined time and with limit Develop a routine habit. Best is to focus in the early morning as there are no other requests Sleep is crucial. Get enough sleep. Do a complete shutdown in the evening....

January 4, 2021 · 1 min · 77 words · Khoa

How to make tiled image in SwiftUI

Issue #737 Use resizingMode of .tile with a tile image from https://www.transparenttextures.com/ Image("transparentTile") .resizable(capInsets: .init(), resizingMode: .tile) .scaleEffect(2) .aspectRatio(contentMode: .fit) .frame(maxWidth: .infinity, maxHeight: .infinity) .clipped()

January 2, 2021 · 1 min · 25 words · Khoa

How to use WebView in SwiftUI

Issue #736 struct MyWebView: NSViewRepresentable { let url: URL @Binding var isLoading: Bool func makeCoordinator() -> Coordinator { Coordinator(parent: self) } func makeNSView(context: Context) -> WKWebView { let view = WKWebView() view.navigationDelegate = context.coordinator view.load(URLRequest(url: url)) return view } func updateNSView(_ nsView: WKWebView, context: Context) { } class Coordinator: NSObject, WKNavigationDelegate { let parent: MyWebView init(parent: MyWebView) { self.parent = parent } func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { parent....

January 2, 2021 · 1 min · 88 words · Khoa

How to use GeometryReader in SwiftUI

Issue #735 From my previous post How to use flexible frame in SwiftUI we know that certain views have different frame behaviors. 2 of them are .overlay and GeometryReader that takes up whole size proposed by parent. By default GeometryReader takes up whole width and height of parent, and align its content as .topLeading struct ContentView_Previews: PreviewProvider { static var previews: some View { VStack { Rectangle() .fill(Color.gray) .overlay( GeometryReader { geo in Text("\(Int(geo....

January 1, 2021 · 1 min · 192 words · Khoa

How to use flexible frame in SwiftUI

Issue #734 In SwiftUI there are fixed frame and flexible frame modifiers. Fixed frame Positions this view within an invisible frame with the specified size. Use this method to specify a fixed size for a view’s width, height, or both. If you only specify one of the dimensions, the resulting view assumes this view’s sizing behavior in the other dimension. VStack { Ellipse() .fill(Color.purple) .frame(width: 200, height: 100) Ellipse() .fill(Color.blue) ....

January 1, 2021 · 7 min · 1320 words · Khoa

How to disable scrolling in NSTextView for macOS

Issue #733 NSTextView has this handy method to make scrollable NSTextView NSTextView.scrollableTextView(). The solution is to get to the responder outside enclosing NSScrollView, in my case it is the SwiftUI hosting view class DisabledScrollTextView: NSTextView { override func scrollWheel(with event: NSEvent) { // 1st nextResponder is NSClipView // 2nd nextResponder is NSScrollView // 3rd nextResponder is NSResponder SwiftUIPlatformViewHost self.nextResponder?.nextResponder?.nextResponder?.scrollWheel(with: event) } } Then we can construct with our new DisabledScrollTextView.scrollableTextView

December 31, 2020 · 1 min · 70 words · Khoa

How to override attribute string in Swift

Issue #732 Use NSMutableAttributedString and add attribute for whole range let a: NSAttributedString let m: NSMutableAttributedString = NSMutableAttributedString(attributedString: a) let range = NSRange(location: 0, length: a.length) m.addAttribute(.backgroundColor, value: NSColor.clear, range: range)

December 31, 2020 · 1 min · 31 words · Khoa

How to make view appear with delay in SwiftUI

Issue #731 Sometimes we don’t want to show progress view right away HUDProgressView() .transition( AnyTransition.asymmetric( insertion: AnyTransition.opacity.animation(Animation.default.delay(1)), removal: AnyTransition.opacity) )

December 31, 2020 · 1 min · 20 words · Khoa

How to make attributed string Text in SwiftUI for macOS

Issue #730 Use NSTextField with maximumNumberOfLines import AppKit import SwiftUI struct AttributedText: NSViewRepresentable { let attributedString: NSAttributedString init(_ attributedString: NSAttributedString) { self.attributedString = attributedString } func makeNSView(context: Context) -> NSTextField { let textField = NSTextField() textField.lineBreakMode = .byClipping textField.maximumNumberOfLines = 0 textField.isBordered = false return textField } func updateNSView(_ nsView: NSTextField, context: Context) { nsView.attributedStringValue = attributedString } } TextField has problem with wrapping, we can use TextView struct AttributedTextView: NSViewRepresentable { typealias NSViewType = NSScrollView let attributedText: NSAttributedString?...

December 31, 2020 · 1 min · 154 words · Khoa

How to do copy paste delete in Swift for macOS

Issue #729 @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @IBAction func copy(_ sender: Any) { print("copy", sender) } @IBAction func paste(_ sender: Any) { print("paste", sender) } } For delete, we can listen to keyDown in NSWindow class MyWindow: NSWindow { override func keyDown(with event: NSEvent) { super.keyDown(with: event) guard let deleteScalar = UnicodeScalar(NSDeleteCharacter), event.charactersIgnoringModifiers == String(deleteScalar) else { return } NotificationCenter.default.post(Notification(name: .didKeyboardDeleteItem)) } }

December 30, 2020 · 1 min · 64 words · Khoa

How to make simple NSItemProvider in Swift

Issue #728 NSItemProvider(object: StringProvider(string: string)) class StringProvider: NSObject, NSItemProviderWriting { let string: String init(string: String) { self.string = string super.init() } static var writableTypeIdentifiersForItemProvider: [String] { return [(kUTTypeData) as String] } func loadData( withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Void ) -> Progress? { let data = string.data(using: .utf8) completionHandler(data, nil) return Progress(totalUnitCount: 100) } }

December 30, 2020 · 1 min · 59 words · Khoa

How to use hashtag raw string in Swift

Issue #727 Use # in Swift 5 to specify raw string, for example regular expression #"^#?(?:[0-9a-fA-F]{3}){1,2}$"# Read more https://www.hackingwithswift.com/articles/162/how-to-use-raw-strings-in-swift

December 27, 2020 · 1 min · 19 words · Khoa

How to make UserDefaults property wrapper

Issue #726 @propertyWrapper struct UserDefault<Value> { let key: String let defaultValue: Value let container: UserDefaults = .standard var wrappedValue: Value { get { return container.object(forKey: key) as? Value ?? defaultValue } set { container.set(newValue, forKey: key) } } } Then we can use it as property and provide default value final class KeepHistoryService { @UserDefault(key: "keepHistoryCheckDate", defaultValue: nil) var checkDate: Date?

December 26, 2020 · 1 min · 61 words · Khoa

How to use Set to check for bool in Swift

Issue #725 When you want to check for existence using Bool, consider using Set over Dictionary with Bool, as Set guarantee uniqueness. If using Dictionary instead, the value for key is Optional<Bool> where we have to check for both optional and true false within. struct Book: Hashable { let id: UUID let name: String } let book1 = Book(id: UUID(), name: "1") let book2 = Book(id: UUID(), name: "2") func useDictionary() { var hasChecked: [Book: Bool] = [:] hasChecked[book1] = true print(hasChecked[book1] == Optional<Bool>(true)) print(hasChecked[book2] == Optional<Bool>....

December 26, 2020 · 1 min · 100 words · Khoa

How to make visual effect blur in SwiftUI for macOS

Issue #724 We can use .blur modifier, but with VisualEffectView gives us more options for material and blending mode. public struct VisualEffectView: NSViewRepresentable { let material: NSVisualEffectView.Material let blendingMode: NSVisualEffectView.BlendingMode public init( material: NSVisualEffectView.Material = .contentBackground, blendingMode: NSVisualEffectView.BlendingMode = .withinWindow ) { self.material = material self.blendingMode = blendingMode } public func makeNSView(context: Context) -> NSVisualEffectView { let visualEffectView = NSVisualEffectView() visualEffectView.material = material visualEffectView.blendingMode = blendingMode visualEffectView.state = NSVisualEffectView.State.active return visualEffectView } public func updateNSView(_ visualEffectView: NSVisualEffectView, context: Context) { visualEffectView....

December 26, 2020 · 1 min · 88 words · Khoa