Last active
August 26, 2022 09:00
-
-
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…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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