Skip to content

Instantly share code, notes, and snippets.

@douglashill
douglashill / test image export quality.m
Created November 25, 2014 11:01
Compress images with ImageIO at a range of compression qualities
@import Foundation;
@import ImageIO;
BOOL exportAtVariousCompressionQualities(NSURL *sourceLocation, NSURL *exportLocation, NSError **error)
{
if (![[NSFileManager defaultManager] createDirectoryAtURL:exportLocation withIntermediateDirectories:YES attributes:nil error:error]) {
return NO;
}
CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)(sourceLocation), NULL);
@douglashill
douglashill / ReduceMotionScrollView.swift
Created October 21, 2018 16:10
A UIScrollView subclass that honours the reduce motion accessibility setting
// Douglas Hill, October 2018
import UIKit
/**
A scroll view that honours the reduce motion accessibility setting.
If reduce motion is enabled, animated adjustments to contentOffset
will use a cross dissolve instead of translation.
@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;
}
@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 / message-to-nil-changes-variable-to-nil.m
Created May 24, 2021 15:43
Sending a message to nil is supposed to do nothing in Objective-C, but here it’s changing the local variable error to nil. Tested with Xcode 12.5 on macOS 11.3.1.
NSError *error = [NSError errorWithDomain:@"domain" code:123 userInfo:nil];
[(NSFileHandle *)nil seekToOffset:0 error:&error];
assert(error != nil); // 💥 Not OK. The error has gone!
@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 / UIImage+DHImageDecoding.m
Last active March 5, 2021 06:20 — forked from tonymillion/gist:6716935
Do not use this to decode an image without blocking the main thread, because it does block the main thread for non-obvious reasons.
@import ImageIO;
@implementation UIImage (DHImageDecoding)
/// Warning: do not use. This looks like it should work, but it blocks the main thread for non-obvious reasons.
+ (UIImage *)dh_decodedImageWithData:(NSData *)data
{
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
if (source == NULL) {
return nil;
@douglashill
douglashill / LazyLet.swift
Created April 22, 2020 08:04
A Swift property wrapper that implements ‘lazy let’. I.e. a read-only property that loads its value when first read. Not safe for access from multiple threads.
/// A Swift property wrapper that implements ‘lazy let’. I.e. a read-only property that loads its value when first read.
/// Not safe for access from multiple threads.
/// Does not work the same as the lazy keyboard because the property initialiser will run before self is available.
/// Adapted from https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md
@propertyWrapper enum LazyLet<Value> {
case uninitialised(() -> Value)
case initialised(Value)
init(wrappedValue: @autoclosure @escaping () -> Value) {
self = .uninitialised(wrappedValue)
@douglashill
douglashill / SidebarTest.swift
Created October 9, 2020 18:18
Trivial Catalyst test app to see if `primaryBackgroundStyle = .sidebar` works to get a translucent blurry sidebar on Big Sur
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
private var _window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {