LookinAutoLayoutConstraint.m 7.6 KB

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