CALayer+RecursiveClone.m 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //
  2. // CALayer+RecursiveClone.m
  3. // SVGKit-iOS
  4. //
  5. // Created by adam on 22/04/2013.
  6. // Copyright (c) 2013 na. All rights reserved.
  7. //
  8. #import "CALayer+RecursiveClone.h"
  9. @implementation CALayer (RecursiveClone)
  10. -(CALayer*) cloneRecursively
  11. {
  12. return [self cloneOptionallRecurse:TRUE];
  13. }
  14. -(CALayer*) cloneShallow
  15. {
  16. return [self cloneOptionallRecurse:FALSE];
  17. }
  18. -(CALayer*) cloneOptionallRecurse:(BOOL) shouldRecurse
  19. {
  20. CALayer* clone = [[self class] layer]; // Apple official method for duplicating a layer correctly but leaving all properties empty
  21. if( [clone isKindOfClass:[CALayer class]])
  22. {
  23. CALayer* specificClone = clone;
  24. CALayer* selfSpecific = self;
  25. specificClone.bounds = selfSpecific.bounds; // don't use Frame! According to Apple's docs, it's officially unsupported for writes!
  26. specificClone.position = selfSpecific.position; // don't use Frame! According to Apple's docs, it's officially unsupported for writes!
  27. specificClone.zPosition = selfSpecific.zPosition;
  28. specificClone.anchorPoint = selfSpecific.anchorPoint;
  29. specificClone.anchorPointZ = selfSpecific.anchorPointZ;
  30. specificClone.transform = selfSpecific.transform;
  31. specificClone.hidden = selfSpecific.hidden;
  32. specificClone.doubleSided = selfSpecific.doubleSided;
  33. specificClone.geometryFlipped = selfSpecific.geometryFlipped;
  34. specificClone.sublayerTransform = selfSpecific.sublayerTransform;
  35. specificClone.mask = [selfSpecific.mask cloneRecursively];
  36. specificClone.masksToBounds = selfSpecific.masksToBounds;
  37. specificClone.contents = selfSpecific.contents;
  38. specificClone.contentsRect = selfSpecific.contentsRect;
  39. specificClone.contentsGravity = selfSpecific.contentsGravity;
  40. specificClone.contentsScale = selfSpecific.contentsScale;
  41. specificClone.contentsCenter = selfSpecific.contentsCenter;
  42. specificClone.minificationFilter = selfSpecific.minificationFilter;
  43. specificClone.magnificationFilter = selfSpecific.magnificationFilter;
  44. specificClone.minificationFilterBias = selfSpecific.minificationFilterBias;
  45. specificClone.opaque = selfSpecific.opaque;
  46. specificClone.needsDisplayOnBoundsChange = selfSpecific.needsDisplayOnBoundsChange;
  47. if( [specificClone respondsToSelector:@selector(drawsAsynchronously)]) // Apple Bug: iOS6+ only, but unmarked in source header
  48. specificClone.drawsAsynchronously = selfSpecific.drawsAsynchronously;
  49. specificClone.edgeAntialiasingMask = selfSpecific.edgeAntialiasingMask;
  50. specificClone.backgroundColor = selfSpecific.backgroundColor;
  51. specificClone.cornerRadius = selfSpecific.cornerRadius;
  52. specificClone.borderWidth = selfSpecific.borderWidth;
  53. specificClone.borderColor = selfSpecific.borderColor;
  54. specificClone.opacity = selfSpecific.opacity;
  55. specificClone.compositingFilter = selfSpecific.compositingFilter;
  56. specificClone.filters = [selfSpecific.filters copy];
  57. specificClone.backgroundFilters = [selfSpecific.backgroundFilters copy];
  58. specificClone.shouldRasterize = selfSpecific.shouldRasterize;
  59. specificClone.rasterizationScale = selfSpecific.rasterizationScale;
  60. specificClone.shadowColor = selfSpecific.shadowColor;
  61. specificClone.shadowOpacity = selfSpecific.shadowOpacity;
  62. specificClone.shadowOffset = selfSpecific.shadowOffset;
  63. specificClone.shadowRadius = selfSpecific.shadowRadius;
  64. specificClone.shadowPath = selfSpecific.shadowPath;
  65. specificClone.name = selfSpecific.name;
  66. specificClone.style = [selfSpecific.style copy];
  67. }
  68. if( [clone isKindOfClass:[CAGradientLayer class]])
  69. {
  70. CAGradientLayer* specificClone = (CAGradientLayer*) clone;
  71. CAGradientLayer* selfSpecific = (CAGradientLayer*) self;
  72. specificClone.startPoint = selfSpecific.startPoint;
  73. specificClone.endPoint = selfSpecific.endPoint;
  74. specificClone.type = selfSpecific.type;
  75. specificClone.colors = [selfSpecific.colors copy];
  76. specificClone.locations = [selfSpecific.locations copy];
  77. }
  78. if( [clone isKindOfClass:[CAShapeLayer class]])
  79. {
  80. CAShapeLayer* specificClone = (CAShapeLayer*) clone;
  81. CAShapeLayer* selfSpecific = (CAShapeLayer*) self;
  82. specificClone.path = selfSpecific.path;
  83. specificClone.fillColor = selfSpecific.fillColor;
  84. specificClone.strokeColor = selfSpecific.strokeColor;
  85. specificClone.lineWidth = selfSpecific.lineWidth;
  86. specificClone.lineCap = selfSpecific.lineCap;
  87. }
  88. if( [clone isKindOfClass:[CATextLayer class]])
  89. {
  90. CATextLayer* specificClone = (CATextLayer*) clone;
  91. CATextLayer* selfSpecific = (CATextLayer*) self;
  92. specificClone.string = selfSpecific.string;
  93. specificClone.font = selfSpecific.font;
  94. specificClone.fontSize = selfSpecific.fontSize;
  95. specificClone.foregroundColor = selfSpecific.foregroundColor;
  96. specificClone.wrapped = selfSpecific.wrapped;
  97. specificClone.truncationMode = selfSpecific.truncationMode;
  98. specificClone.alignmentMode = selfSpecific.alignmentMode;
  99. }
  100. if( shouldRecurse )
  101. {
  102. for( CALayer* subLayer in self.sublayers )
  103. {
  104. [clone addSublayer:[subLayer cloneRecursively]];
  105. }
  106. }
  107. return clone;
  108. }
  109. @end