[YogaKit] support auto apply layout.
- support auto apply layout - build Yoga & YogaKit framework as staticlib; - update YogaKitSample.
This commit is contained in:
@@ -35,3 +35,88 @@ static const void* kYGYogaAssociatedKey = &kYGYogaAssociatedKey;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static const void* kYGBoundsSizeAssociatedKey = &kYGBoundsSizeAssociatedKey;
|
||||
static void YogaSwizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector);
|
||||
|
||||
@implementation UIView (YogaKitAutoApplyLayout)
|
||||
|
||||
+ (void)load {
|
||||
static dispatch_once_t onceToken = 0;
|
||||
dispatch_once(&onceToken, ^{
|
||||
YogaSwizzleInstanceMethod(self, @selector(initWithFrame:), @selector(_yoga_initWithFrame:));
|
||||
YogaSwizzleInstanceMethod(self, @selector(setFrame:), @selector(_yoga_setFrame:));
|
||||
YogaSwizzleInstanceMethod(self, @selector(setBounds:), @selector(_yoga_setBounds:));
|
||||
});
|
||||
}
|
||||
|
||||
- (CGSize)_yoga_boundsSize {
|
||||
NSValue *value = (NSValue *)objc_getAssociatedObject(self, kYGBoundsSizeAssociatedKey);
|
||||
|
||||
return value ? value.CGSizeValue : CGSizeMake(YGUndefined, YGUndefined);
|
||||
}
|
||||
|
||||
- (void)set_yoga_boundsSize:(CGSize)size {
|
||||
objc_setAssociatedObject(self,
|
||||
kYGBoundsSizeAssociatedKey,
|
||||
[NSValue valueWithCGSize:size],
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (instancetype)_yoga_initWithFrame:(CGRect)frame {
|
||||
id _self = [self _yoga_initWithFrame:frame];
|
||||
if (_self) {
|
||||
[self _yoga_applyLayout];
|
||||
}
|
||||
|
||||
return _self;
|
||||
}
|
||||
|
||||
- (void)_yoga_setFrame:(CGRect)frame {
|
||||
[self _yoga_setFrame:frame];
|
||||
|
||||
[self _yoga_applyLayout];
|
||||
}
|
||||
|
||||
- (void)_yoga_setBounds:(CGRect)bounds {
|
||||
[self _yoga_setBounds:bounds];
|
||||
|
||||
[self _yoga_applyLayout];
|
||||
}
|
||||
|
||||
- (void)_yoga_applyLayout {
|
||||
if (self.isYogaEnabled && self.yoga.isEnabled) {
|
||||
CGSize size = self.bounds.size;
|
||||
CGSize prev = self._yoga_boundsSize;
|
||||
if (!CGSizeEqualToSize(size, prev)) {
|
||||
self._yoga_boundsSize = size;
|
||||
[self.yoga applyLayoutPreservingOrigin:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static void YogaSwizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector) {
|
||||
if (!cls || !originalSelector || !swizzledSelector) {
|
||||
return;
|
||||
}
|
||||
|
||||
Method originalMethod = class_getInstanceMethod(cls, originalSelector);
|
||||
Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
|
||||
if (!originalMethod || !swizzledMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
IMP swizzledIMP = method_getImplementation(swizzledMethod);
|
||||
if (class_addMethod(cls, originalSelector, swizzledIMP, method_getTypeEncoding(swizzledMethod))) {
|
||||
class_replaceMethod(cls,
|
||||
swizzledSelector,
|
||||
method_getImplementation(originalMethod),
|
||||
method_getTypeEncoding(originalMethod));
|
||||
} else {
|
||||
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user