M80AttributedLabelAttachment.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //
  2. // M80AttributedLabelAttachment.m
  3. // M80AttributedLabel
  4. //
  5. // Created by amao on 13-8-31.
  6. // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
  7. //
  8. #import "M80AttributedLabelAttachment.h"
  9. void deallocCallback(void* ref)
  10. {
  11. }
  12. CGFloat ascentCallback(void *ref)
  13. {
  14. M80AttributedLabelAttachment *image = (__bridge M80AttributedLabelAttachment *)ref;
  15. CGFloat ascent = 0;
  16. CGFloat height = [image boxSize].height;
  17. switch (image.alignment)
  18. {
  19. case M80ImageAlignmentTop:
  20. ascent = image.fontAscent;
  21. break;
  22. case M80ImageAlignmentCenter:
  23. {
  24. CGFloat fontAscent = image.fontAscent;
  25. CGFloat fontDescent = image.fontDescent;
  26. CGFloat baseLine = (fontAscent + fontDescent) / 2 - fontDescent;
  27. ascent = height / 2 + baseLine;
  28. }
  29. break;
  30. case M80ImageAlignmentBottom:
  31. ascent = height - image.fontDescent;
  32. break;
  33. default:
  34. break;
  35. }
  36. return ascent;
  37. }
  38. CGFloat descentCallback(void *ref)
  39. {
  40. M80AttributedLabelAttachment *image = (__bridge M80AttributedLabelAttachment *)ref;
  41. CGFloat descent = 0;
  42. CGFloat height = [image boxSize].height;
  43. switch (image.alignment)
  44. {
  45. case M80ImageAlignmentTop:
  46. {
  47. descent = height - image.fontAscent;
  48. break;
  49. }
  50. case M80ImageAlignmentCenter:
  51. {
  52. CGFloat fontAscent = image.fontAscent;
  53. CGFloat fontDescent = image.fontDescent;
  54. CGFloat baseLine = (fontAscent + fontDescent) / 2 - fontDescent;
  55. descent = height / 2 - baseLine;
  56. }
  57. break;
  58. case M80ImageAlignmentBottom:
  59. {
  60. descent = image.fontDescent;
  61. break;
  62. }
  63. default:
  64. break;
  65. }
  66. return descent;
  67. }
  68. CGFloat widthCallback(void* ref)
  69. {
  70. M80AttributedLabelAttachment *image = (__bridge M80AttributedLabelAttachment *)ref;
  71. return [image boxSize].width;
  72. }
  73. #pragma mark - M80AttributedLabelImage
  74. @interface M80AttributedLabelAttachment ()
  75. - (CGSize)calculateContentSize;
  76. - (CGSize)attachmentSize;
  77. @end
  78. @implementation M80AttributedLabelAttachment
  79. + (M80AttributedLabelAttachment *)attachmentWith:(id)content
  80. margin:(UIEdgeInsets)margin
  81. alignment:(M80ImageAlignment)alignment
  82. maxSize:(CGSize)maxSize
  83. {
  84. M80AttributedLabelAttachment *attachment = [[M80AttributedLabelAttachment alloc]init];
  85. attachment.content = content;
  86. attachment.margin = margin;
  87. attachment.alignment = alignment;
  88. attachment.maxSize = maxSize;
  89. return attachment;
  90. }
  91. - (CGSize)boxSize
  92. {
  93. CGSize contentSize = [self attachmentSize];
  94. if (_maxSize.width > 0 &&_maxSize.height > 0 &&
  95. contentSize.width > 0 && contentSize.height > 0)
  96. {
  97. contentSize = [self calculateContentSize];
  98. }
  99. return CGSizeMake(contentSize.width + _margin.left + _margin.right,
  100. contentSize.height+ _margin.top + _margin.bottom);
  101. }
  102. #pragma mark - 辅助方法
  103. - (CGSize)calculateContentSize
  104. {
  105. CGSize attachmentSize = [self attachmentSize];
  106. CGFloat width = attachmentSize.width;
  107. CGFloat height = attachmentSize.height;
  108. CGFloat newWidth = _maxSize.width;
  109. CGFloat newHeight = _maxSize.height;
  110. if (width <= newWidth &&
  111. height<= newHeight)
  112. {
  113. return attachmentSize;
  114. }
  115. CGSize size;
  116. if (width / height > newWidth / newHeight)
  117. {
  118. size = CGSizeMake(newWidth, newWidth * height / width);
  119. }
  120. else
  121. {
  122. size = CGSizeMake(newHeight * width / height, newHeight);
  123. }
  124. return size;
  125. }
  126. - (CGSize)attachmentSize
  127. {
  128. CGSize size = CGSizeZero;
  129. if ([_content isKindOfClass:[UIImage class]])
  130. {
  131. size = [((UIImage *)_content) size];
  132. }
  133. else if ([_content isKindOfClass:[UIView class]])
  134. {
  135. size = [((UIView *)_content) bounds].size;
  136. }
  137. return size;
  138. }
  139. @end