LookinAutoLayoutConstraint.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. //
  2. // LookinAutoLayoutConstraint.m
  3. // Lookin
  4. //
  5. // Created by Li Kai on 2019/9/28.
  6. // https://lookin.work
  7. //
  8. #import "LookinAutoLayoutConstraint.h"
  9. #import "LookinObject.h"
  10. @implementation LookinAutoLayoutConstraint
  11. #if TARGET_OS_IPHONE
  12. + (instancetype)instanceFromNSConstraint:(NSLayoutConstraint *)constraint isEffective:(BOOL)isEffective firstItemType:(LookinConstraintItemType)firstItemType secondItemType:(LookinConstraintItemType)secondItemType {
  13. LookinAutoLayoutConstraint *instance = [LookinAutoLayoutConstraint new];
  14. instance.effective = isEffective;
  15. instance.active = constraint.active;
  16. instance.shouldBeArchived = constraint.shouldBeArchived;
  17. instance.firstItem = [LookinObject instanceWithObject:constraint.firstItem];
  18. instance.firstItemType = firstItemType;
  19. instance.firstAttribute = constraint.firstAttribute;
  20. instance.relation = constraint.relation;
  21. instance.secondItem = [LookinObject instanceWithObject:constraint.secondItem];
  22. instance.secondItemType = secondItemType;
  23. instance.secondAttribute = constraint.secondAttribute;
  24. instance.multiplier = constraint.multiplier;
  25. instance.constant = constraint.constant;
  26. instance.priority = constraint.priority;
  27. instance.identifier = constraint.identifier;
  28. return instance;
  29. }
  30. - (void)setFirstAttribute:(NSLayoutAttribute)firstAttribute {
  31. _firstAttribute = firstAttribute;
  32. [self _assertUnknownAttribute:firstAttribute];
  33. }
  34. - (void)setSecondAttribute:(NSLayoutAttribute)secondAttribute {
  35. _secondAttribute = secondAttribute;
  36. [self _assertUnknownAttribute:secondAttribute];
  37. }
  38. - (void)_assertUnknownAttribute:(NSLayoutAttribute)attribute {
  39. // 以下几个 assert 用来帮助发现那些系统私有的定义,正式发布时应该去掉这几个 assert
  40. if (attribute > 21 && attribute < 32) {
  41. NSAssert(NO, nil);
  42. }
  43. if (attribute > 37) {
  44. NSAssert(NO, nil);
  45. }
  46. }
  47. #endif
  48. + (NSString *)descriptionWithItemObject:(LookinObject *)object type:(LookinConstraintItemType)type detailed:(BOOL)detailed {
  49. switch (type) {
  50. case LookinConstraintItemTypeNil:
  51. return detailed ? @"Nil" : @"nil";
  52. case LookinConstraintItemTypeSelf:
  53. return detailed ? @"Self" : @"self";
  54. case LookinConstraintItemTypeSuper:
  55. return detailed ? @"Superview" : @"super";
  56. case LookinConstraintItemTypeView:
  57. case LookinConstraintItemTypeLayoutGuide:
  58. return detailed ? [NSString stringWithFormat:@"<%@: %@>", object.shortSelfClassName, object.memoryAddress] : [NSString stringWithFormat:@"(%@*)", object.shortSelfClassName];
  59. default:
  60. NSAssert(NO, @"");
  61. return detailed ? [NSString stringWithFormat:@"<%@: %@>", object.shortSelfClassName, object.memoryAddress] : [NSString stringWithFormat:@"(%@*)", object.shortSelfClassName];
  62. }
  63. }
  64. + (NSString *)descriptionWithAttribute:(NSLayoutAttribute)attribute {
  65. switch (attribute) {
  66. case 0 :
  67. // 在某些业务里确实会出现这种情况,在 Reveal 和 UI Debugger 里也是这么显示的
  68. return @"notAnAttribute";
  69. case 1:
  70. return @"left";
  71. case 2:
  72. return @"right";
  73. case 3:
  74. return @"top";
  75. case 4:
  76. return @"bottom";
  77. case 5:
  78. return @"leading";
  79. case 6:
  80. return @"trailing";
  81. case 7:
  82. return @"width";
  83. case 8:
  84. return @"height";
  85. case 9:
  86. return @"centerX";
  87. case 10:
  88. return @"centerY";
  89. case 11:
  90. return @"lastBaseline";
  91. case 12:
  92. return @"baseline";
  93. case 13:
  94. return @"firstBaseline";
  95. case 14:
  96. return @"leftMargin";
  97. case 15:
  98. return @"rightMargin";
  99. case 16:
  100. return @"topMargin";
  101. case 17:
  102. return @"bottomMargin";
  103. case 18:
  104. return @"leadingMargin";
  105. case 19:
  106. return @"trailingMargin";
  107. case 20:
  108. return @"centerXWithinMargins";
  109. case 21:
  110. return @"centerYWithinMargins";
  111. // 以下都是和 AutoResizingMask 有关的,这里的定义是从系统 UI Debugger 里抄过来的,暂时没在官方文档里发现它们的公开定义
  112. case 32:
  113. return @"minX";
  114. case 33:
  115. return @"minY";
  116. case 34:
  117. return @"midX";
  118. case 35:
  119. return @"midY";
  120. case 36:
  121. return @"maxX";
  122. case 37:
  123. return @"maxY";
  124. default:
  125. NSAssert(NO, @"");
  126. return [NSString stringWithFormat:@"unknownAttr(%@)", @(attribute)];
  127. }
  128. }
  129. + (NSString *)symbolWithRelation:(NSLayoutRelation)relation {
  130. switch (relation) {
  131. case -1:
  132. return @"<=";
  133. case 0:
  134. return @"=";
  135. case 1:
  136. return @">=";
  137. default:
  138. NSAssert(NO, @"");
  139. return @"?";
  140. }
  141. }
  142. + (NSString *)descriptionWithRelation:(NSLayoutRelation)relation {
  143. switch (relation) {
  144. case -1:
  145. return @"LessThanOrEqual";
  146. case 0:
  147. return @"Equal";
  148. case 1:
  149. return @"GreaterThanOrEqual";
  150. default:
  151. NSAssert(NO, @"");
  152. return @"?";
  153. }
  154. }
  155. #pragma mark - <NSSecureCoding>
  156. + (BOOL)supportsSecureCoding {
  157. return YES;
  158. }
  159. - (void)encodeWithCoder:(NSCoder *)aCoder {
  160. [aCoder encodeBool:self.effective forKey:@"effective"];
  161. [aCoder encodeBool:self.active forKey:@"active"];
  162. [aCoder encodeBool:self.shouldBeArchived forKey:@"shouldBeArchived"];
  163. [aCoder encodeObject:self.firstItem forKey:@"firstItem"];
  164. [aCoder encodeInteger:self.firstItemType forKey:@"firstItemType"];
  165. [aCoder encodeInteger:self.firstAttribute forKey:@"firstAttribute"];
  166. [aCoder encodeInteger:self.relation forKey:@"relation"];
  167. [aCoder encodeObject:self.secondItem forKey:@"secondItem"];
  168. [aCoder encodeInteger:self.secondItemType forKey:@"secondItemType"];
  169. [aCoder encodeInteger:self.secondAttribute forKey:@"secondAttribute"];
  170. [aCoder encodeDouble:self.multiplier forKey:@"multiplier"];
  171. [aCoder encodeDouble:self.constant forKey:@"constant"];
  172. [aCoder encodeDouble:self.priority forKey:@"priority"];
  173. [aCoder encodeObject:self.identifier forKey:@"identifier"];
  174. }
  175. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  176. if (self = [super init]) {
  177. self.effective = [aDecoder decodeBoolForKey:@"effective"];
  178. self.active = [aDecoder decodeBoolForKey:@"active"];
  179. self.shouldBeArchived = [aDecoder decodeBoolForKey:@"shouldBeArchived"];
  180. self.firstItem = [aDecoder decodeObjectForKey:@"firstItem"];
  181. self.firstItemType = [aDecoder decodeIntegerForKey:@"firstItemType"];
  182. self.firstAttribute = [aDecoder decodeIntegerForKey:@"firstAttribute"];
  183. self.relation = [aDecoder decodeIntegerForKey:@"relation"];
  184. self.secondItem = [aDecoder decodeObjectForKey:@"secondItem"];
  185. self.secondItemType = [aDecoder decodeIntegerForKey:@"secondItemType"];
  186. self.secondAttribute = [aDecoder decodeIntegerForKey:@"secondAttribute"];
  187. self.multiplier = [aDecoder decodeDoubleForKey:@"multiplier"];
  188. self.constant = [aDecoder decodeDoubleForKey:@"constant"];
  189. self.priority = [aDecoder decodeDoubleForKey:@"priority"];
  190. self.identifier = [aDecoder decodeObjectForKey:@"identifier"];
  191. }
  192. return self;
  193. }
  194. @end