YPTabItem.m 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. //
  2. // YPTabItem.m
  3. // YPTabBarController
  4. //
  5. // Created by 喻平 on 15/8/11.
  6. // Copyright (c) 2015年 YPTabBarController. All rights reserved.
  7. //
  8. #import "YPTabItem.h"
  9. @interface YPTabItem ()
  10. @property (nonatomic, strong) UIButton *badgeButton;
  11. @property (nonatomic, strong) UIView *doubleTapView;
  12. @property (nonatomic, assign) CGFloat verticalOffset;
  13. @property (nonatomic, assign) CGFloat spacing;
  14. @property (nonatomic, strong) CALayer *separatorLayer;
  15. @property (nonatomic, assign) CGFloat numberBadgeMarginTop;
  16. @property (nonatomic, assign) CGFloat numberBadgeCenterMarginRight;
  17. @property (nonatomic, assign) CGFloat numberBadgeTitleHorizonalSpace;
  18. @property (nonatomic, assign) CGFloat numberBadgeTitleVerticalSpace;
  19. @property (nonatomic, assign) CGFloat dotBadgeMarginTop;
  20. @property (nonatomic, assign) CGFloat dotBadgeCenterMarginRight;
  21. @property (nonatomic, assign) CGFloat dotBadgeSideLength;
  22. @property (nonatomic, copy) void (^doubleTapHandler)(void);
  23. @end
  24. @implementation YPTabItem
  25. - (instancetype)init {
  26. self = [super init];
  27. if (self) {
  28. [self awakeFromNib];
  29. }
  30. return self;
  31. }
  32. - (void)awakeFromNib {
  33. [super awakeFromNib];
  34. self.backgroundColor=[UIColor whiteColor];
  35. self.badgeButton = [UIButton buttonWithType:UIButtonTypeCustom];
  36. self.badgeButton.userInteractionEnabled = NO;
  37. self.badgeButton.clipsToBounds = YES;
  38. [self addSubview:self.badgeButton];
  39. _badgeStyle = YPTabItemBadgeStyleNumber;
  40. self.badge = 0;
  41. // _verticalOffset = 5;
  42. // _spacing = 5;
  43. // _contentHorizontalCenter = YES;
  44. // self.badgeTitleColor = [UIColor whiteColor];
  45. // self.badgeTitleFont = [UIFont systemFontOfSize:13];
  46. // self.badgeBackgroundColor = BADGE_BG_COLOR_DEFAULT;
  47. // self.numberBadgeFrame = YPTabItemBadgeFrameMake(2, 20, 16);
  48. // self.dotBadgeFrame = YPTabItemBadgeFrameMake(5, 25, 10);
  49. }
  50. - (void)setHighlighted:(BOOL)highlighted {
  51. }
  52. - (void)setContentHorizontalCenter:(BOOL)contentHorizontalCenter {
  53. _contentHorizontalCenter = contentHorizontalCenter;
  54. if (!_contentHorizontalCenter) {
  55. self.verticalOffset = 0;
  56. self.spacing = 0;
  57. }
  58. if (self.superview) {
  59. [self layoutSubviews];
  60. }
  61. }
  62. - (void)setContentHorizontalCenterWithVerticalOffset:(CGFloat)verticalOffset
  63. spacing:(CGFloat)spacing {
  64. self.verticalOffset = verticalOffset;
  65. self.spacing = spacing;
  66. self.contentHorizontalCenter = YES;
  67. }
  68. - (void)layoutSubviews {
  69. [super layoutSubviews];
  70. if ([self imageForState:UIControlStateNormal] && self.contentHorizontalCenter) {
  71. CGSize titleSize = self.titleLabel.frame.size;
  72. CGSize imageSize = self.imageView.frame.size;
  73. titleSize = CGSizeMake(ceilf(titleSize.width), ceilf(titleSize.height));
  74. CGFloat totalHeight = (imageSize.height + titleSize.height + self.spacing);
  75. self.imageEdgeInsets = UIEdgeInsetsMake(- (totalHeight - imageSize.height - self.verticalOffset), 0, 0, - titleSize.width);
  76. self.titleEdgeInsets = UIEdgeInsetsMake(self.verticalOffset, - imageSize.width, - (totalHeight - titleSize.height), 0);
  77. } else {
  78. self.imageEdgeInsets = UIEdgeInsetsZero;
  79. self.titleEdgeInsets = UIEdgeInsetsZero;
  80. }
  81. }
  82. - (void)setSelected:(BOOL)selected {
  83. [super setSelected:selected];
  84. if (self.doubleTapView) {
  85. self.doubleTapView.hidden = !selected;
  86. }
  87. }
  88. - (void)setDoubleTapHandler:(void (^)(void))handler {
  89. _doubleTapHandler = handler;
  90. if (!self.doubleTapView) {
  91. self.doubleTapView = [[UIView alloc] initWithFrame:self.bounds];
  92. [self addSubview:self.doubleTapView];
  93. UITapGestureRecognizer *doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
  94. action:@selector(doubleTapped:)];
  95. doubleRecognizer.numberOfTapsRequired = 2;
  96. [self.doubleTapView addGestureRecognizer:doubleRecognizer];
  97. }
  98. }
  99. - (void)doubleTapped:(UITapGestureRecognizer *)recognizer {
  100. if (self.doubleTapHandler) {
  101. self.doubleTapHandler();
  102. }
  103. }
  104. - (void)setFrame:(CGRect)frame {
  105. [super setFrame:frame];
  106. _frameWithOutTransform = frame;
  107. if (self.doubleTapView) {
  108. self.doubleTapView.frame = self.bounds;
  109. }
  110. }
  111. #pragma mark - Title and Image
  112. - (void)setTitle:(NSString *)title {
  113. _title = title;
  114. [self setTitle:title forState:UIControlStateNormal];
  115. }
  116. - (void)setTitleColor:(UIColor *)titleColor {
  117. _titleColor = titleColor;
  118. [self setTitleColor:titleColor forState:UIControlStateNormal];
  119. }
  120. - (void)setTitleSelectedColor:(UIColor *)titleSelectedColor {
  121. _titleSelectedColor = titleSelectedColor;
  122. [self setTitleColor:titleSelectedColor forState:UIControlStateSelected];
  123. }
  124. - (void)setTitleFont:(UIFont *)titleFont {
  125. _titleFont = titleFont;
  126. if ([UIDevice currentDevice].systemVersion.integerValue >= 8) {
  127. self.titleLabel.font = titleFont;
  128. }
  129. }
  130. - (void)setImage:(UIImage *)image {
  131. _image = image;
  132. [self setImage:image forState:UIControlStateNormal];
  133. }
  134. - (void)setSelectedImage:(UIImage *)selectedImage {
  135. _selectedImage = selectedImage;
  136. [self setImage:selectedImage forState:UIControlStateSelected];
  137. }
  138. #pragma mark - Badge
  139. - (void)setBadge:(NSInteger)badge {
  140. _badge = badge;
  141. [self updateBadge];
  142. }
  143. - (void)setBadgeStyle:(YPTabItemBadgeStyle)badgeStyle {
  144. _badgeStyle = badgeStyle;
  145. [self updateBadge];
  146. }
  147. - (void)updateBadge {
  148. if (self.badgeStyle == YPTabItemBadgeStyleNumber) {
  149. if (self.badge == 0) {
  150. self.badgeButton.hidden = YES;
  151. } else {
  152. NSString *badgeStr = @(self.badge).stringValue;
  153. if (self.badge > 99) {
  154. badgeStr = @"99+";
  155. } else if (self.badge < -99) {
  156. badgeStr = @"-99+";
  157. }
  158. CGSize size = [badgeStr boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
  159. options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
  160. attributes:@{NSFontAttributeName : self.badgeButton.titleLabel.font}
  161. context:nil].size;
  162. CGFloat width = ceilf(size.width) + self.numberBadgeTitleHorizonalSpace;
  163. CGFloat height = ceilf(size.height) + self.numberBadgeTitleVerticalSpace;
  164. width = MAX(width, height);
  165. self.badgeButton.frame = CGRectMake(self.bounds.size.width - width / 2 - self.numberBadgeCenterMarginRight,
  166. self.numberBadgeMarginTop,
  167. width,
  168. height);
  169. self.badgeButton.layer.cornerRadius = self.badgeButton.bounds.size.height / 2;
  170. [self.badgeButton setTitle:badgeStr forState:UIControlStateNormal];
  171. self.badgeButton.hidden = NO;
  172. }
  173. } else if (self.badgeStyle == YPTabItemBadgeStyleDot) {
  174. [self.badgeButton setTitle:nil forState:UIControlStateNormal];
  175. self.badgeButton.frame = CGRectMake(self.bounds.size.width - self.dotBadgeCenterMarginRight - self.dotBadgeSideLength,
  176. self.dotBadgeMarginTop,
  177. self.dotBadgeSideLength,
  178. self.dotBadgeSideLength);
  179. self.badgeButton.layer.cornerRadius = self.badgeButton.bounds.size.height / 2;
  180. self.badgeButton.hidden = NO;
  181. }
  182. }
  183. - (void)setNumberBadgeMarginTop:(CGFloat)marginTop
  184. centerMarginRight:(CGFloat)centerMarginRight
  185. titleHorizonalSpace:(CGFloat)titleHorizonalSpace
  186. titleVerticalSpace:(CGFloat)titleVerticalSpace {
  187. self.numberBadgeMarginTop = marginTop;
  188. self.numberBadgeCenterMarginRight = centerMarginRight;
  189. self.numberBadgeTitleHorizonalSpace = titleHorizonalSpace;
  190. self.numberBadgeTitleVerticalSpace = titleVerticalSpace;
  191. [self updateBadge];
  192. }
  193. - (void)setDotBadgeMarginTop:(CGFloat)marginTop
  194. centerMarginRight:(CGFloat)centerMarginRight
  195. sideLength:(CGFloat)sideLength {
  196. self.dotBadgeMarginTop = marginTop;
  197. self.dotBadgeCenterMarginRight = centerMarginRight;
  198. self.dotBadgeSideLength = sideLength;
  199. [self updateBadge];
  200. }
  201. - (void)setBadgeBackgroundColor:(UIColor *)badgeBackgroundColor {
  202. _badgeBackgroundColor = badgeBackgroundColor;
  203. self.badgeButton.backgroundColor = badgeBackgroundColor;
  204. }
  205. - (void)setBadgeTitleColor:(UIColor *)badgeTitleColor {
  206. _badgeTitleColor = badgeTitleColor;
  207. [self.badgeButton setTitleColor:badgeTitleColor forState:UIControlStateNormal];
  208. }
  209. - (void)setBadgeBackgroundImage:(UIImage *)badgeBackgroundImage {
  210. _badgeBackgroundImage = badgeBackgroundImage;
  211. [self.badgeButton setBackgroundImage:badgeBackgroundImage forState:UIControlStateNormal];
  212. }
  213. - (void)setBadgeTitleFont:(UIFont *)badgeTitleFont {
  214. _badgeTitleFont = badgeTitleFont;
  215. self.badgeButton.titleLabel.font = badgeTitleFont;
  216. [self updateBadge];
  217. }
  218. @end