-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUIView+NestedXib.m
135 lines (106 loc) · 4.57 KB
/
UIView+NestedXib.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// UIView+NestedXib.m
// Iconic
//
// Created by Aleksey Garbarev on 03.09.14.
// Copyright (c) 2014 Code Monastery. All rights reserved.
//
#import "UIView+NestedXib.h"
#import <objc/runtime.h>
@implementation UIView (NestedXib)
static NSMutableSet *loadingXibs;
static NSArray *propertiesToTransfer;
id(*originalImp)(id, SEL, NSCoder *);
+ (void)load
{
IMP customImp = class_getMethodImplementation([UIView class], @selector(nested_xib_awakeAfterUsingCoder:));
Method originalMethod = class_getInstanceMethod([UIView class], @selector(awakeAfterUsingCoder:));
originalImp = (id(*)(id,SEL,NSCoder*))method_setImplementation(originalMethod, customImp);
}
+ (void)initialize
{
loadingXibs = [NSMutableSet new];
propertiesToTransfer = @[@"frame", @"autoresizesSubviews", @"autoresizingMask", @"hidden", @"userInteractionEnabled", @"translatesAutoresizingMaskIntoConstraints"];
[super initialize];
}
- (id)nested_xib_awakeAfterUsingCoder:(NSCoder *)aDecoder
{
id result = nil;
if ([self isKindOfClass:[UIView class]]) {
NSString *nestedXibName = nil;
nestedXibName = [[self class] xibName];
if (nestedXibName.length > 0 && ![[self class] isLoadingXib:nestedXibName]) {
result = [[self class] viewFromXib:nestedXibName originalView:self];
CFRelease((__bridge const void*)self);
CFRetain((__bridge const void*)result);
}
}
if (!result) {
result = originalImp(self, @selector(awakeAfterUsingCoder:), aDecoder);
}
return result;
}
+ (NSString *)xibName
{
NSString *guessName = NSStringFromClass([self class]);
if ([[NSBundle bundleForClass:[self class]] pathForResource:guessName ofType:@"nib"]) {
return guessName;
} else {
return nil;
}
}
+ (BOOL)isLoadingXib:(NSString *)name
{
return [loadingXibs containsObject:name];
}
+ (id)viewFromXib:(NSString *)xibName originalView:(UIView *)original
{
[loadingXibs addObject:xibName];
if ([[original subviews] count] > 0) {
NSLog(@"Warning: placeholder view contains (%d) subviews. They will be replaced by view from %@ xib", [[original subviews] count], xibName);
}
id result = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] firstObject];
[loadingXibs removeObject:xibName];
[self transferPropertiesFromView:original toView:result];
return result;
}
+ (void)transferPropertiesFromView:(UIView *)src toView:(UIView *)dst
{
//Transferring autolayout
for (NSLayoutConstraint *constraint in src.constraints) {
BOOL replaceFirstItem = [constraint firstItem] == src;
BOOL replaceSecondItem = [constraint secondItem] == src;
id firstItem = replaceFirstItem ? dst : constraint.firstItem;
id secondItem = replaceSecondItem ? dst : constraint.secondItem;
NSLayoutConstraint *copy = [NSLayoutConstraint constraintWithItem:firstItem attribute:constraint.firstAttribute relatedBy:constraint.relation toItem:secondItem attribute:constraint.secondAttribute multiplier:constraint.multiplier constant:constraint.constant];
[dst addConstraint:copy];
}
//Transferring properties
for (NSString *name in propertiesToTransfer) {
id value = [src valueForKey:name];
if ([dst validateValue:&value forKey:name error:nil]) {
[dst setValue:value forKey:name];
}
}
}
- (void)drawInterfaceBuilderRect:(CGRect)rect
{
NSString *xibName = [[[self class] xibName] stringByAppendingPathExtension:@"xib"];
if (xibName) {
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor colorWithWhite:0.93 alpha:1] setFill];
CGContextFillRect(context, self.bounds);
UILabel *label = [[UILabel alloc] initWithFrame:self.bounds];
label.lineBreakMode = NSLineBreakByWordWrapping;
label.numberOfLines = 0;
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor colorWithWhite:0.78 alpha:1];
UIFont *baseFont = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:33];
UIFont *subtitleFont = [baseFont fontWithSize:24];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"Nested Xib\n" attributes:@{NSFontAttributeName : baseFont}];
[string appendAttributedString:[[NSAttributedString alloc] initWithString:xibName attributes:@{NSFontAttributeName : subtitleFont}]];
label.attributedText = string;
[label drawRect:self.bounds];
}
}
@end