Skip to content

Instantly share code, notes, and snippets.

@steipete
Last active August 26, 2022 09:00
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steipete/9725247 to your computer and use it in GitHub Desktop.
Save steipete/9725247 to your computer and use it in GitHub Desktop.
Simple solution that allows to block the parent layoutSubview-triggering, see https://gist.github.com/steipete/9723421. In short, changing a frame of a subview outside of layoutSubviews will trigger the parent's layoutSubviews. Sometimes this is not what we want, especially when you consider performance. In my case (http://pspdfkit.com) this was…
@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"
#import <objc/runtime.h>
static NSString *const PSPDFSuppressLayoutKey = @"pspdf_suppressSetNeedsLayout";
@interface PSPDFSuppressLayoutTriggerLayer : CALayer @end
@implementation PSPDFSuppressLayoutTriggerLayer
- (void)setNeedsLayout {
if (![[self valueForKey:PSPDFSuppressLayoutKey] boolValue]) {
[super setNeedsLayout];
}
}
@end
@implementation UIView (PSPDFKitAdditions)
- (void)pspdf_performWithoutTriggeringSetNeedsLayout:(dispatch_block_t)block {
CALayer *layer = self.layer;
// Change layer to be our custom subclass.
if (![layer isKindOfClass:PSPDFSuppressLayoutTriggerLayer.class]) {
// Check both classes to see and break if KVO is used here.
if ([layer.class isEqual:CALayer.class] && [layer.class isEqual:object_getClass(layer)]) {
object_setClass(self.layer, PSPDFSuppressLayoutTriggerLayer.class);
}else {
// While we could use dynamic subclassing, that amount of complexity isn't needed in our case.
// If we're a different layer type, the generic KVC store value is simply ignored, so no need to quit.
NSLog(@"View has a custom layer - not changing.");
}
}
if (![[layer valueForKey:PSPDFSuppressLayoutKey] boolValue]) {
[layer setValue:@YES forKey:PSPDFSuppressLayoutKey];
block();
[layer setValue:@NO forKey:PSPDFSuppressLayoutKey];
}else {
// No need to set flag again. Allows to be called this multiple times.
block();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment