Skip to content

Instantly share code, notes, and snippets.

@douglashill
douglashill / updateSafeAreaForKeyboardFromNotification.swift
Last active June 25, 2023 16:11
Avoid the keyboard by leveraging additionalSafeAreaInsets.
// Avoids the keyboard in a UIKit app by leveraging additionalSafeAreaInsets.
// You can put this in the root view controller so the whole app will avoid the keyboard.
// Only tested on iOS 13.3.
// Made for https://douglashill.co/reading-app/
@objc func updateSafeAreaForKeyboardFromNotification(_ notification: Notification) {
guard let endFrameInScreenCoords = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
return
}
// Please consider whether the force unwrap here is safe for your own use case.
@douglashill
douglashill / FindReplace.swift
Created February 11, 2020 16:13
Swift script helper to find and replace an array of substitutions.
/// Performs a textual find and replace with the specified substitutions on all files in directory (recursive) that have the specified filename extensions.
func find(_ substitutions: [(find: String, replace: String)], allowedExtensions: Set<String>, directory rootURL: URL) {
let fileURLs = FileManager.default.enumerator(at: rootURL, includingPropertiesForKeys: nil)!.map {
$0 as! URL
}
.filter {
$0.hasDirectoryPath == false
}
.filter {
allowedExtensions.contains($0.pathExtension)
@douglashill
douglashill / PlatformDifferences.swift
Created December 13, 2019 20:35
The current file I use to smooth over API differences between AppKit and UIKit.
// Douglas Hill, April 2017
// From https://douglashill.co/reading-app/
#if os(macOS)
import AppKit
public typealias Colour = NSColor
public typealias Font = NSFont
public typealias FontDescriptor = NSFontDescriptor
public typealias Image = NSImage
@douglashill
douglashill / ReadingStrings.swift
Created December 8, 2019 21:32
Tries really hard to read a string from a file. Brute forces encodings if necessary.
// Douglas Hill, December 2019
// Made for https://douglashill.co/reading-app/
import Foundation
/// Tries really hard to read a string from a file.
///
/// Brute forces encodings if necessary. This will only fail if the file can’t be interpreted
/// in any encoding, or if some other error occurs like not being able to read from the file.
///
@douglashill
douglashill / KeyboardTabBarController.swift
Last active December 13, 2019 21:54
A UITabBarController subclass that allows navigating between tabs using cmd+number on a hardware keyboard.
// Douglas Hill, May 2019
// Find the latest version of this file at https://github.com/douglashill/KeyboardKit
import UIKit
/// A tab bar controller that allows navigating between tabs using cmd+number on a hardware keyboard.
/// So cmd+1 for the first tab, cmd+2 for the second tab etc.
public class KeyboardTabBarController: UITabBarController {
public override var keyCommands: [UIKeyCommand]? {
@douglashill
douglashill / KeyboardScrollView.swift
Last active May 6, 2021 00:47
A UIScrollView subclass that allows scrolling using a hardware keyboard like NSScrollView. Supports arrow keys, option + arrow keys, command + arrow keys, space bar, page up, page down, home and end.
// Douglas Hill, November 2019
// Find the latest version of this file at https://github.com/douglashill/KeyboardKit
import UIKit
/// A scroll view that allows scrolling using a hardware keyboard like `NSScrollView`.
/// Supports arrow keys, option + arrow keys, command + arrow keys, space bar, page up, page down, home and end.
/// Limitations:
/// - Paging scroll views (isPagingEnabled = true) are not supported yet.
/// - The scroll view must become its own delegate so setting the delegate is not supported yet.
@douglashill
douglashill / main.m
Last active October 6, 2023 18:10
A minimal iOS 13 app that is set up in Objective-C rather than using a storyboard and UIApplicationSceneManifest
@import UIKit;
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
@end
@implementation SceneDelegate
@synthesize window = _window;
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
@douglashill
douglashill / AdaptiveTraitsContainer.swift
Created April 13, 2019 01:15
Experimenting altering an iOS app size class to be responsive to the Dynamic Text size.
import UIKit
/// A wrapper view controller that makes the horizontal size class
/// be based on both the Dynamic Text size and the width available.
class AdaptiveTraitsContainer: UIViewController {
let wrappedViewController: UIViewController
init(wrappedViewController: UIViewController) {
self.wrappedViewController = wrappedViewController
super.init(nibName: nil, bundle: nil)
@douglashill
douglashill / KeyboardTableView.swift
Last active March 30, 2023 22:01
A UITableView that allows navigation and selection using a hardware keyboard.
// Douglas Hill, December 2018
// Made for https://douglashill.co/reading-app/
// Find the latest version of this file at https://github.com/douglashill/KeyboardKit
import UIKit
/// A table view that allows navigation and selection using a hardware keyboard.
/// Only supports a single section.
class KeyboardTableView: UITableView {
// These properties may be set or overridden to provide discoverability titles for key commands.
@douglashill
douglashill / PSPDFTableViewCell+LayoutMarginsGuide.m
Created November 16, 2018 07:50
Alternative for a table view cell’s content view’s layoutMarginsGuide that works on iOS 10.
@implementation PSPDFTableViewCell // UITableViewCell subclass
/**
On iOS 10, constraints involving a UITableViewCell’s contentView’s layoutMarginsGuide are removed for some
reason before the cell appears, which breaks the layout. This layout guide is a working alternative.
*/
- (UILayoutGuide *)pspdf_layoutMarginsGuide {
if (@available(iOS 11.0, *)) {
return self.contentView.layoutMarginsGuide;
}