Skip to content

Instantly share code, notes, and snippets.

Peter Steinberger steipete

Block or report user

Report or block steipete

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@steipete
steipete / UIView+AnimationContext.swift
Last active Aug 10, 2019 — forked from CodingMeSwiftly/UIView+AnimationContext.swift
An extension on UIView to retrieve information about the animation context the view is currently in.
View UIView+AnimationContext.swift
import UIKit
extension UIView {
struct AnimationContext {
public let duration: TimeInterval
public let timingParameters: UITimingCurveProvider?
}
}
extension UIView {
@steipete
steipete / UIView+AnimationContext.swift
Created Aug 10, 2019 — forked from CodingMeSwiftly/UIView+AnimationContext.swift
An extension on UIView to retrieve information about the animation context the view is currently in.
View UIView+AnimationContext.swift
import UIKit
extension UIView {
struct AnimationContext {
public let duration: TimeInterval
public let timingParameters: UITimingCurveProvider?
}
}
extension UIView {
@steipete
steipete / Runtime.m
Created Aug 7, 2019
pspdf_swizzleSelectorWithBlock, pspdf_swizzleSelector. Please use your own prefix when you copy these.
View Runtime.m
// http://defagos.github.io/yet_another_article_about_method_swizzling/ (Thank you!!)
// Returns the original implementation
static _Nullable IMP pspdf_swizzleSelector(Class clazz, SEL selector, IMP newImplementation) {
NSCParameterAssert(clazz);
NSCParameterAssert(selector);
NSCParameterAssert(newImplementation);
// If the method does not exist for this class, do nothing.
const Method method = class_getInstanceMethod(clazz, selector);
if (!method) {
@steipete
steipete / SomeObjCFile.m
Created Aug 7, 2019
HACK around FB6940492: Mac Catalyst: Crash when presenting view controllers. Call early.
View SomeObjCFile.m
/**
HACK around FB6940492: Mac Catalyst: Crash when presenting view controllers
'NSRangeException', reason: 'Cannot remove an observer <UINSSceneViewController 0x600003558790> for the key path "view.window.screen.contentLayoutRect" from <UINSSceneViewController 0x600003558790> because it is not registered as an observer.'
0 CoreFoundation 0x00007fff3b20f183 __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff71719b64 objc_exception_throw + 48
2 Foundation 0x00007fff3d8ca2aa -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 578
3 Foundation 0x00007fff3d8ca01b -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 74
4 Foundation 0x00007fff3d8e2898 -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:context:] + 190
@steipete
steipete / Helper.m
Last active Aug 6, 2019
Mac Catalyst: Get the NSWindow from a UIWindow
View Helper.m
// This code fetches the matching NSWindow from an UIWindow.
let nsWindowFromUIWindow = ^(UIWindow *referenceUIWindow) {
// This is public AppKit API and should be safe to use.
NSArray *const nsWindows = [NSClassFromString(@"NSApplication") valueForKeyPath:@"sharedApplication.windows"];
for (id nsWindow in nsWindows) {
NSArray<UIWindow *> *uiWindows;
@try {
/*
NSWindow hosts one or multiple UIWindows.
(e.g. your app window + the text selection window).
@steipete
steipete / AppDelegate.swift
Last active Aug 2, 2019
Create menu in mac Catalyst via UIMenuBuilder (beta 4) - (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder;
View AppDelegate.swift
// AppDelegate.swift:
// macCatalyst: Create menu
override func buildMenu(with builder: UIMenuBuilder) {
guard builder.system == .main else { return }
// The format menu doesn't make sense
builder.remove(menu: .format)
// Add Open command
@steipete
steipete / PSPDFEnvironment.m
Last active Mar 26, 2019
PSPDFApplicationIsTerminating - detect application termination on iOS and macOS. License: MIT. Taken out of the commercial PSPDFKit PDF SDK. http://pspdfkit.com
View PSPDFEnvironment.m
static _Atomic(BOOL) _applicationWillTerminate = NO;
__attribute__((constructor)) static void PSPDFInstallAppWillTerminateHandler(void) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[NSNotificationCenter.defaultCenter addObserverForName:UIApplicationWillTerminateNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
_applicationWillTerminate = YES;
PSPDFLogWarning(@"Application shutdown event detected.");
}];
});
}
View UndoManagerWorkaround.swift
extension UndoManager {
@objc func workaround_pspdf_endUndoGrouping() {
guard self.groupingLevel > 0 else { return }
self.workaround_pspdf_endUndoGrouping()
}
// Ensure this is only called once!
fileprivate static func InstallWorkaroundForRdar46395110() {
let originalSelector = #selector(UndoManager.endUndoGrouping)
let swizzledSelector = #selector(UndoManager.workaround_pspdf_endUndoGrouping)
@steipete
steipete / TempDir.swift
Created Oct 25, 2018
Based on https://nshipster.com/temporary-files/ I ran some experiments with the recommended replacement API for NSTemporaryDirectory(). It's not straightforward.
View TempDir.swift
// tl;dr: FileManager.default.url(for:in:appropriateFor:create:) has unexpected behavior in Simulator and creates temporary folders outside the tmp/ directory.
let tmpDirClassic = NSTemporaryDirectory()
print("tmpDirClassic: \(tmpDirClassic)")
// This is the same code, just syntax sugar for NSTemporaryDirectory()
// https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/FileManager.swift#L1420-L1422
let tmpDirClassicNewShim = FileManager.default.temporaryDirectory
print("tmpDirClassicNewShim: \(tmpDirClassicNewShim)")
// Simulator: /Users/steipete/Library/Developer/CoreSimulator/Devices/31C05637-B9C9-482C-A6CE-D063A7CECF64/data/Containers/Data/Application/A68D11A4-88BA-4FCF-A8B1-D102945D0740/tmp/
View UIKit+iOSMac.h
#import <Foundation/Foundation.h>
@class NSString, UHASToolbarItem;
__attribute__((weak_import)) @interface _UIWindowToolbarItem : NSObject
@property(readonly, copy, nonatomic) NSString *label;
@property(readonly, copy, nonatomic) NSString *identifier;
- (id)initWithIdentifier:(id)arg1;
You can’t perform that action at this time.