Updated this for the first time in awhile in late 2020.
- Enable iCloud
- Disable iCloud mail
- Display to medium
- Turn up trackpad speed
// Smart little helper to find main thread hangs. Enable in appDidFinishLaunching. | |
// Only available with source code in DEBUG mode. | |
@interface PSPDFHangDetector : NSObject | |
+ (void)startHangDetector; | |
@end | |
@implementation PSPDFHangDetector | |
+ (void)startHangDetector { | |
#ifdef DEBUG |
Storyboard Segues initially seem like a pretty cool way to construct interfaces using minimal glue code. But actually, ordinary nibs already support this, and in a much more flexible way.
Certainly, a Storyboard lets you bind a button action up to display a view controller with no code, but in practice you will usually want to pass some data to the new controller, depending on which button you used to get there, and this means implementing the -prepareForSegue:sender: method, which rapidly becomes a giant if/elseif statement of doom, negating most of the benefit of the codeless segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"modalSegue"])
{
ModalViewController *controller = (ModalViewController *)segue.destination;
controller.someProperty = someValue;
# Mac OS X | |
*.DS_Store | |
# Xcode | |
*.pbxuser | |
*.mode1v3 | |
*.mode2v3 | |
*.perspectivev3 | |
*.xcuserstate | |
project.xcworkspace/ |
Singleton.h | |
------------- | |
@protocol Singleton | |
@optional | |
+ (instancetype)sharedInstance; | |
@end |
@interface UIView (PSPDFKitAdditions) | |
// Allows to change frame/bounds without triggering `layoutSubviews` on the parent. | |
// Not needed for changes that are performed within `layoutSubviews`. | |
- (void)pspdf_performWithoutTriggeringSetNeedsLayout:(dispatch_block_t)block; | |
@end | |
#import "UIView+PSPDFKitAdditions.h" |
A number of tech news outlets, including WIRED, GigaOm, and MIT Technology Review, have recently started writing about Multipeer Connectivity ("one weird trick that the NSA hates"). Since the NSHipster article on the subject has been linked to in a lot of this coverage, I wanted to share some additional thoughts on the matter:
Multipeer Connectivity(http://nshipster.com/multipeer-connectivity/) represents a significant shift in the opposite direction of how we conventionally think about mobile applications. Nearly every app on your phone operates in a client-server model, with the device making requests to remote cloud services to send and receive messages, photos, and videos. The [
- (NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath { | |
return @"More"; | |
} | |
- (void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath { | |
NSLog(@"I wanted to be a pretty public API, but then time ran out and they forgot me..."); | |
// Hide the More/Delete menu. | |
[self setEditing:NO animated:YES]; | |
} |
In this article, I'm going to explore a way that we can create views that implement custom Core Animation property animations in a natural way.
As we know, layers in iOS come in two flavours: Backing layers and hosted layers. The only difference between them is that the view acts as the layer delegate for its backing layer, but not for any hosted sublayers.
In order to implement the UIView
transactional animation blocks, UIView
disables all animations by default and then re-enables them individually as required. It does this using the actionForLayer:forKey:
method.
Somewhat strangely, UIView
doesn't enable animations for every property that CALayer
does by default. A notable example is the layer.contents
property, which is animatable by default for a hosted layer, but cannot be animated using a UIView
animation block.
@interface FullscreenWindow : UIWindow @end | |
@implementation FullscreenWindow | |
- (void)setRootViewController:(UIViewController *)rootVC { | |
// Try to clear the existing interface orientation, fixes rdar://18906964. | |
// Apparantly in iOS 8.1 the interface orientation doesn't correctly clears out, | |
// which then leads to weird rotation issues. | |
@try {[rootVC setValue:@(UIInterfaceOrientationPortrait) forKey:NSStringFromSelector(@selector(interfaceOrientation))];} | |
@catch (NSException *exception) {} | |
[super setRootViewController:rootVC]; |