How to make checked NSButton in AppKit

Issue #433 Use Omnia for convenient style and isOn property let checkButton = NSButton(checkboxWithTitle: "", target: nil, action: nil) checkButton.stylePlain(title: "Autosave", color: R.color.text, font: R.font.text) checkButton.isOn = true

September 30, 2019 · 1 min · 28 words · Khoa

How to save files in sandboxed macOS app

Issue #432 Read Container Directories and File System Access When you adopt App Sandbox, your application has access to the following locations: The app container directory. Upon first launch, the operating system creates a special directory for use by your app—and only by your app—called a container. Each user on a system gets an individual container for your app, within their home directory; your app has unfettered read/write access to the container for the user who ran it....

September 28, 2019 · 1 min · 92 words · Khoa

How to use marked in WKWebView in AppKit

Issue #429 Use https://github.com/markedjs/marked <!doctype html> <html> <head> <meta charset="utf-8"/> <title>Marked in the browser</title> </head> <body> <div id="content"></div> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <script> document.getElementById('content').innerHTML = marked(`# Marked in the browser\n\nRendered by **marked**.`); </script> </body> </html> Should use back tick instead of ' to deal with multiline string, and escape back tick let markdown = markdown.replacingOccurrences(of: "`", with: "\\`") marked(`\(markdown)`); webView.loadHTMLString(string, baseURL: nil) For WKWebView to load even local content, need to enable Outgoing connections, and maybe Incoming connections in Sandbox

September 26, 2019 · 1 min · 78 words · Khoa

How to enable NSMenuItem in AppKit

Issue #428 Need to set target let item = NSMenuItem( title: title, action: #selector(onMenuItemClicked(_:)), keyEquivalent: "" ) item.target = self Sometimes, need to check autoenablesItems Indicates whether the menu automatically enables and disables its menu items. This property contains a Boolean value, indicating whether the menu automatically enables and disables its menu items. If set to true, menu items of the menu are automatically enabled and disabled according to rules computed by the NSMenuValidation informal protocol....

September 25, 2019 · 1 min · 84 words · Khoa

How to use generic NSCollectionView in macOS

Issue #427 See CollectionViewHandler Use ClickedCollectionView to detect clicked index for context menu. Embed NSCollectionView inside NSScrollView to enable scrolling import AppKit public class CollectionViewHandler<Item: Equatable, Cell: NSCollectionViewItem> : NSObject, NSCollectionViewDataSource, NSCollectionViewDelegateFlowLayout { public let layout = NSCollectionViewFlowLayout() public let scrollView = NSScrollView() public let collectionView = ClickedCollectionView() public var items = [Item]() public var itemSize: () -> CGSize = { .zero } public var configure: (Item, Cell) -> Void = { _, _ in } override init() { super....

September 24, 2019 · 2 min · 261 words · Khoa

How to use throttle and debounce in RxSwift

Issue #426 throttle https://rxmarbles.com/#throttle Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration. This operator makes sure that no two elements are emitted in less then dueTime. .throttle(.milliseconds(500), scheduler: MainScheduler.instance) In a time window, only the first item gets emitted. 💡 In other words, in a time window, take first and discard following. For example, when failure, we show error message but don’t want to show error messages consecutively....

September 19, 2019 · 1 min · 196 words · Khoa

How to use flatMap and compactMap in Swift

Issue #425 flatMap: map and flatten array of arrays compactMap: map and flatten array of optionals

September 19, 2019 · 1 min · 16 words · Khoa

How to constrain to views inside UICollectionViewCell in iOS

Issue #422 To constrain views outside to elements inside UICollectionViewCell, we can use UILayoutGuide. Need to make layout guide the same constraints as the real elements let imageViewGuide = UILayoutGuide() collectionView.addLayoutGuide(imageViewGuide) NSLayoutConstraint.on([ imageViewGuide.topAnchor.constraint(equalTo: collectionView.topAnchor, constant: 16), imageViewGuide.heightAnchor.constraint(equalTo: collectionView.heightAnchor, multiplier: 0.5) ]) NSLayoutConstraint.on([ loadingIndicator.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor), loadingIndicator.centerYAnchor.constraint(equalTo: imageViewGuide.centerYAnchor) ])

September 17, 2019 · 1 min · 47 words · Khoa

How to secure CVC in STPPaymentCardTextField in Stripe for iOS

Issue #421 private func maskCvcIfAny() { guard let view = paymentTextField.subviews.first(where: { !($0 is UIImageView) }), let cvcField = view.subviews .compactMap({ $0 as? UITextField }) .first(where: { $0.tag == 2 && ($0.accessibilityLabel ?? "").lowercased().contains("cvc") }) else { return } cvcField.isSecureTextEntry = true } where tag is in STPPaymentCardTextFieldViewModel.h typedef NS_ENUM(NSInteger, STPCardFieldType) { STPCardFieldTypeNumber, STPCardFieldTypeExpiration, STPCardFieldTypeCVC, STPCardFieldTypePostalCode, }; Also, need to check accessibilityLabel in STPPaymentCardTextField.m - (NSString *)defaultCVCPlaceholder { if (self.viewModel.brand == STPCardBrandAmex) { return STPLocalizedString(@"CVV", @"Label for entering CVV in text field"); } else { return STPLocalizedString(@"CVC", @"Label for entering CVC in text field"); } }

September 16, 2019 · 1 min · 96 words · Khoa

How to easily parse deep json in Swift

Issue #414 Codable is awesome, but sometimes we just need to quickly get value in a deepy nested JSON. In the same way I did for Dart How to resolve deep json object in Dart, let’s make that in Swift. See https://github.com/onmyway133/Omnia/blob/master/Sources/Shared/JSON.swift public func resolve<T>(_ jsonDictionary: [String: Any], keyPath: String) -> T? { var current: Any? = jsonDictionary keyPath.split(separator: ".").forEach { component in if let maybeInt = Int(component), let array = current as?...

September 12, 2019 · 1 min · 177 words · Khoa

How to speed up GMSMarker in Google Maps for iOS

Issue #412 Google Maps with a lot of pin, and no clustering can have bad performance if there are complex view in the marker. The workaround is to use manual layout and rasterization shouldRasterize When the value of this property is true, the layer is rendered as a bitmap in its local coordinate space and then composited to the destination with any other content. Shadow effects and any filters in the filters property are rasterized and included in the bitmap....

September 10, 2019 · 2 min · 345 words · Khoa

How to support drag and drop in UICollectionView iOS

Issue #411 See DragAndDrop example class ViewController: UIViewController, UICollectionViewDropDelegate, UICollectionViewDragDelegate { // MARK: - UICollectionViewDragDelegate func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { let controller = leftController let provider = NSItemProvider( object: controller.imageForCell(indexPath: indexPath) ) let dragItem = UIDragItem(itemProvider: provider) dragItem.localObject = indexPath return [dragItem] } // MARK: - UICollectionViewDropDelegate func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { let destinationIndexPath: IndexPath if let indexPath = coordinator....

September 10, 2019 · 1 min · 114 words · Khoa

How to support drag and drop in NSView

Issue #410 import AppKit import Anchors class DraggingView: NSView { var didDrag: ((FileInfo) -> Void)? let highlightView = NSView() override init(frame frameRect: NSRect) { super.init(frame: frameRect) registerForDraggedTypes([ .fileURL ]) highlightView.isHidden = true addSubview(highlightView) activate(highlightView.anchor.edges) highlightView.wantsLayer = true highlightView.layer?.borderColor = NSColor(hex: "#FF6CA8").cgColor highlightView.layer?.borderWidth = 6 } required init?(coder decoder: NSCoder) { fatalError() } override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { highlightView.isHidden = false return NSDragOperation() } override func draggingEnded(_ sender: NSDraggingInfo) { guard let pathAlias = sender....

September 10, 2019 · 1 min · 163 words · Khoa

How to use NSStepper in Appkit

Issue #409 let stepper = NSStepper() let textField = NSTextField(wrappingLabelWithString: "\(myLocalCount)") stepper.integerValue = myLocalCount stepper.minValue = 5 stepper.maxValue = 24 stepper.valueWraps = false stepper.target = self stepper.action = #selector(onStepperChange(_:)) @objc func onStepperChange(_ sender: NSStepper) { myLocalCount = sender.integerValue textField.stringValue = "\(sender.integerValue)" }

September 8, 2019 · 1 min · 42 words · Khoa

How to handle shortcut in AppKit

Issue #408 Podfile pod 'MASShortcut' let shortcut = MASShortcut(keyCode: kVK_ANSI_K, modifierFlags: [.command, .shift]) MASShortcutMonitor.shared()?.register(shortcut, withAction: { self.showPopover(sender: self.statusItem.button) })

September 8, 2019 · 1 min · 19 words · Khoa

How to select file in its directory in AppKit

Issue #407 https://developer.apple.com/documentation/appkit/nsworkspace/1524399-selectfile In macOS 10.5 and later, this method does not follow symlinks when selecting the file. If the fullPath parameter contains any symlinks, this method selects the symlink instead of the file it targets. If you want to select the target file, use the resolvingSymlinksInPath method to resolve any symlinks before calling this method. It is safe to call this method from any thread of your app. NSWorkspace.shared.selectFile( url....

September 7, 2019 · 1 min · 73 words · Khoa

How to use NSProgressIndicator in AppKit

Issue #406 let progressIndicator = NSProgressIndicator() progressIndicator.isIndeterminate = true progressIndicator.style = .spinning progressIndicator.startAnimation(nil)

September 7, 2019 · 1 min · 13 words · Khoa

How to show save panel in AppKit

Issue #405 Enable Read/Write for User Selected File under Sandbox to avoid bridge absent error func showSave( name: String, window: NSWindow ) async -> URL? { let panel = NSSavePanel() panel.directoryURL = FileManager.default.homeDirectoryForCurrentUser panel.nameFieldStringValue = name let response = await panel.beginSheetModal(for: window) if response == .OK { return panel.url } else { return nil } } To save multiple files, use NSOpenPanel let panel = NSOpenPanel() panel.canChooseFiles = false panel.allowsMultipleSelection = false panel....

September 7, 2019 · 1 min · 83 words · Khoa

How to animate NSView using keyframe

Issue #404 let animation = CAKeyframeAnimation(keyPath: "position.y") animation.values = [50, 20, 50] animation.keyTimes = [0.0, 0.5, 1.0] animation.duration = 2 animation.repeatCount = Float.greatestFiniteMagnitude animation.autoreverses = true myView.wantsLayer = true myView.layer?.add(animation, forKey: "bounce")

September 6, 2019 · 1 min · 32 words · Khoa

How to quit macOS on last window closed

Issue #403 https://developer.apple.com/documentation/appkit/nsapplicationdelegate/1428381-applicationshouldterminateafterl?language=objc The application sends this message to your delegate when the application’s last window is closed. It sends this message regardless of whether there are still panels open. (A panel in this case is defined as being an instance of NSPanel or one of its subclasses.) If your implementation returns NO, control returns to the main event loop and the application is not terminated. If you return YES, your delegate’s applicationShouldTerminate: method is subsequently invoked to confirm that the application should be terminated....

September 6, 2019 · 1 min · 95 words · Khoa