SPPageMenu.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. //
  2. // SPPageMenu.h
  3. // SPPageMenu
  4. //
  5. // Created by 乐升平 on 17/10/26. https://github.com/SPStore/SPPageMenu
  6. // Copyright © 2017年 iDress. All rights reserved.
  7. //
  8. #import <UIKit/UIKit.h>
  9. NS_ASSUME_NONNULL_BEGIN
  10. typedef NS_ENUM(NSInteger, SPPageMenuTrackerStyle) {
  11. SPPageMenuTrackerStyleLine = 0, // 下划线,默认与item等宽
  12. SPPageMenuTrackerStyleLineLongerThanItem, // 下划线,比item要长(长度为item的宽+间距)
  13. SPPageMenuTrackerStyleLineAttachment, // 下划线“依恋”样式,此样式下默认宽度为字体的pointSize,你可以通过trackerWidth自定义宽度
  14. SPPageMenuTrackerStyleRoundedRect, // 圆角矩形
  15. SPPageMenuTrackerStyleRect, // 矩形
  16. SPPageMenuTrackerStyleTextZoom NS_ENUM_DEPRECATED_IOS(6_0, 6_0, "该枚举值已经被废弃,请用“selectedItemZoomScale”属性代替"), // 缩放(该枚举已经被废弃,用属性代替的目的是让其余样式可与缩放样式配套使用。如果你同时设置了该枚举和selectedItemZoomScale属性,selectedItemZoomScale优先级高于SPPageMenuTrackerStyleTextZoom
  17. SPPageMenuTrackerStyleNothing // 什么样式都没有
  18. };
  19. typedef NS_ENUM(NSInteger, SPPageMenuPermutationWay) {
  20. SPPageMenuPermutationWayScrollAdaptContent = 0, // 自适应内容,可以左右滑动
  21. SPPageMenuPermutationWayNotScrollEqualWidths, // 等宽排列,不可以滑动,整个内容被控制在pageMenu的范围之内,等宽是根据pageMenu的总宽度对每个item均分
  22. SPPageMenuPermutationWayNotScrollAdaptContent // 自适应内容,不可以滑动,整个内容被控制在pageMenu的范围之内,这种排列方式下,自动计算item之间的间距,itemPadding属性无效
  23. };
  24. typedef NS_ENUM(NSInteger, SPPageMenuTrackerFollowingMode) {
  25. SPPageMenuTrackerFollowingModeAlways = 0, // 外界scrollView拖动时,跟踪器时刻跟随外界scrollView移动
  26. SPPageMenuTrackerFollowingModeEnd, // 外界scrollVie拖动w结束后,跟踪器才开始移动
  27. SPPageMenuTrackerFollowingModeHalf // 外界scrollView拖动距离超过屏幕一半时,跟踪器开始移动
  28. };
  29. typedef NS_ENUM(NSInteger, SPItemImagePosition) {
  30. SPItemImagePositionDefault, // 默认图片在左边
  31. SPItemImagePositionLeft, // 图片在左边
  32. SPItemImagePositionTop, // 图片在上面
  33. SPItemImagePositionRight, // 图片在右边
  34. SPItemImagePositionBottom // 图片在下面
  35. };
  36. @class SPPageMenu;
  37. @protocol SPPageMenuDelegate <NSObject>
  38. @optional
  39. // 若以下2个代理方法同时实现了,只会走第2个代理方法(第2个代理方法包含了第1个代理方法的功能)
  40. - (void)pageMenu:(SPPageMenu *)pageMenu itemSelectedAtIndex:(NSInteger)index;
  41. - (void)pageMenu:(SPPageMenu *)pageMenu itemSelectedFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex;
  42. // 右侧的功能按钮被点击的代理方法
  43. - (void)pageMenu:(SPPageMenu *)pageMenu functionButtonClicked:(UIButton *)functionButton;
  44. @end
  45. @interface SPPageMenu : UIView
  46. // 创建pagMenu
  47. + (instancetype)pageMenuWithFrame:(CGRect)frame trackerStyle:(SPPageMenuTrackerStyle)trackerStyle;
  48. - (instancetype)initWithFrame:(CGRect)frame trackerStyle:(SPPageMenuTrackerStyle)trackerStyle;
  49. /**
  50. * 传递数据
  51. *
  52. * @param items 数组 (数组元素只能是NSString或UIImage类型)
  53. * @param selectedItemIndex 默认选中item的下标
  54. */
  55. - (void)setItems:(nullable NSArray *)items selectedItemIndex:(NSInteger)selectedItemIndex;
  56. @property (nonatomic) NSInteger selectedItemIndex; // 选中的item下标,改变其值可以用于切换选中的item
  57. @property(nonatomic,readonly) NSUInteger numberOfItems; // items的总个数
  58. #if TARGET_INTERFACE_BUILDER
  59. @property (nonatomic, readonly) IBInspectable NSInteger trackerStyle; // 该枚举属性支持storyBoard/xib,方便在storyBoard/xib中创建时直接设置
  60. #else
  61. @property (nonatomic, readonly) SPPageMenuTrackerStyle trackerStyle;
  62. #endif
  63. // item之间的间距,默认30;当排列方式permutationWay为‘SPPageMenuPermutationWayNotScrollAdaptContent’时此属性无效,无效是合理的,不可能做到“不可滑动且自适应内容”然后间距又自定义,这2者相互制约;
  64. @property (nonatomic, assign) CGFloat itemPadding;
  65. @property (nonatomic, strong) UIColor *selectedItemTitleColor; // 选中的item标题颜色
  66. @property (nonatomic, strong) UIColor *unSelectedItemTitleColor; // 未选中的item标题颜色
  67. @property (nonatomic, strong) UIFont *itemTitleFont; // 设置所有item标题字体,不区分选中的item和未选中的item
  68. @property (nonnull, nonatomic, strong) UIFont *selectedItemTitleFont; // 选中的item字体
  69. @property (nonnull, nonatomic, strong) UIFont *unSelectedItemTitleFont; // 未选中的item字体
  70. // 外界的srollView,pageMenu会监听该scrollView的滚动状况,让跟踪器时刻跟随此scrollView滑动;所谓的滚动状况,是指手指拖拽滚动,非手指拖拽不算
  71. @property (nonatomic, strong) UIScrollView *bridgeScrollView;
  72. @property (nonatomic, assign) SPPageMenuPermutationWay permutationWay; // 排列方式
  73. @property (nonatomic, assign) UIEdgeInsets contentInset; // 内容的四周内边距(内容不包括分割线),默认UIEdgeInsetsZero
  74. @property(nonatomic) BOOL bounces; // 边界反弹效果,默认YES
  75. @property(nonatomic) BOOL alwaysBounceHorizontal; // 水平方向上,当内容没有充满scrollView时,滑动scrollView是否有反弹效果,默认YES
  76. // 跟踪器
  77. @property (nonatomic, readonly) UIImageView *tracker; // 跟踪器,它是一个UIImageView类型,你可以拿到该对象去设置一些自己想要的属性,例如颜色,图片等,但是设置frame无效
  78. @property (nonatomic, assign) CGFloat trackerWidth; // 跟踪器的宽度
  79. // 设置跟踪器的高度和圆角半径,矩形和圆角矩形样式下半径参数无效。其余样式下:默认的高度为3,圆角半径为高度的一半。如果你想用默认高度,但是又不想要圆角半径,你可以设置trackerHeight为3,cornerRadius为0,这是去除默认半径的唯一办法
  80. - (void)setTrackerHeight:(CGFloat)trackerHeight cornerRadius:(CGFloat)cornerRadius;
  81. // 跟踪器的跟踪模式
  82. @property (nonatomic, assign) SPPageMenuTrackerFollowingMode trackerFollowingMode;
  83. // 分割线
  84. @property (nonatomic, readonly) UIImageView *dividingLine; // 分割线,你可以拿到该对象设置一些自己想要的属性,如颜色、图片等,如果想要隐藏分割线,拿到该对象直接设置hidden为YES或设置alpha<0.01即可(eg:pageMenu.dividingLine.hidden = YES)
  85. @property (nonatomic) CGFloat dividingLineHeight; // 分割线的高度
  86. // 选中的item缩放系数,默认为1,为1代表不缩放,[0,1)之间缩小,(1,+∞)之间放大,(-1,0)之间"倒立"缩小,(-∞,-1)之间"倒立"放大,为-1"倒立不缩放",如果依然使用了废弃的SPPageMenuTrackerStyleTextZoom样式,则缩放系数默认为1.3
  87. @property (nonatomic) CGFloat selectedItemZoomScale;
  88. @property (nonatomic, assign) BOOL needTextColorGradients; // 是否需要文字渐变,默认为YES
  89. @property (nonatomic, weak) id<SPPageMenuDelegate> delegate;
  90. // 插入item,插入和删除操作时,如果itemIndex超过了了items的个数,则不做任何操作
  91. - (void)insertItemWithTitle:(nullable NSString *)title atIndex:(NSUInteger)itemIndex animated:(BOOL)animated;
  92. - (void)insertItemWithImage:(nullable UIImage *)image atIndex:(NSUInteger)itemIndex animated:(BOOL)animated;
  93. // 如果移除的正是当前选中的item(当前选中的item下标不为0),删除之后,选中的item会切换为上一个item
  94. - (void)removeItemAtIndex:(NSUInteger)itemIndex animated:(BOOL)animated;
  95. - (void)removeAllItems;
  96. - (void)setTitle:(nullable NSString *)title forItemAtIndex:(NSUInteger)itemIndex; // 设置指定item的标题,设置后,仅会有文字
  97. - (nullable NSString *)titleForItemAtIndex:(NSUInteger)itemIndex; // 获取指定item的标题
  98. - (void)setImage:(nullable UIImage *)image forItemAtIndex:(NSUInteger)itemIndex; // 设置指定item的图片,设置后,仅会有图片
  99. - (nullable UIImage *)imageForItemAtIndex:(NSUInteger)itemIndex; // 获取指定item的图片
  100. - (void)setWidth:(CGFloat)width forItemAtIndex:(NSUInteger)itemIndex; // 设置指定item的宽度(如果width为0,item会根据内容自动计算width)
  101. - (CGFloat)widthForItemAtIndex:(NSUInteger)itemIndex; // 获取指定item的宽度
  102. - (void)setEnabled:(BOOL)enaled forItemAtIndex:(NSUInteger)itemIndex; // 设置指定item的enabled状态
  103. - (BOOL)enabledForItemAtIndex:(NSUInteger)itemIndex; // 获取指定item的enabled状态
  104. - (void)setContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets forItemAtIndex:(NSUInteger)itemIndex; // 设置指定item的四周内边距
  105. - (UIEdgeInsets)contentEdgeInsetsForItemAtIndex:(NSUInteger)itemIndex; // 获取指定item的四周内边距
  106. // 设置背景图片,barMetrics只有为UIBarMetricsDefault时才生效,如果外界传进来的backgroundImage调用过- resizableImageWithCapInsets:且参数capInsets不为UIEdgeInsetsZero,则直接用backgroundImage作为背景图; 否则内部会自动调用- resizableImageWithCapInsets:进行拉伸
  107. - (void)setBackgroundImage:(nullable UIImage *)backgroundImage barMetrics:(UIBarMetrics)barMetrics;
  108. - (nullable UIImage *)backgroundImageForBarMetrics:(UIBarMetrics)barMetrics; // 获取背景图片
  109. /**
  110. 同时为指定item设置标题和图片
  111. @param title 标题
  112. @param image 图片
  113. @param imagePosition 图片的位置,分上、左、下、右
  114. @param ratio 图片所占item的比例,图片在左右时默认0.5,图片在上下时默认2.0/3.0
  115. @param imageTitleSpace 图片与标题之间的间距,默认0
  116. @param itemIndex item的下标
  117. */
  118. - (void)setTitle:(nullable NSString *)title image:(nullable UIImage *)image imagePosition:(SPItemImagePosition)imagePosition imageRatio:(CGFloat)ratio imageTitleSpace:(CGFloat)imageTitleSpace forItemIndex:(NSUInteger)itemIndex;
  119. @property (nonatomic, assign) BOOL showFuntionButton; // 是否显示功能按钮(功能按钮显示在最右侧),默认为NO
  120. @property (nonatomic, assign) CGFloat funtionButtonshadowOpacity; // 功能按钮左侧的阴影透明度,如果设置小于等于0,则没有阴影
  121. /**
  122. * 同时为functionButton设置标题和图片
  123. *
  124. * @param title 标题
  125. * @param image 图片
  126. * @param imagePosition 图片的位置,分上、左、下、右
  127. * @param ratio 图片所占item的比例,图片在左右时默认0.5,图片在上下时默认2.0/3.0
  128. * @param imageTitleSpace 图片与标题之间的间距,默认0
  129. * @param state 控件状态
  130. */
  131. - (void)setFunctionButtonTitle:(nullable NSString *)title image:(nullable UIImage *)image imagePosition:(SPItemImagePosition)imagePosition imageRatio:(CGFloat)ratio imageTitleSpace:(CGFloat)imageTitleSpace forState:(UIControlState)state;
  132. // 为functionButton配置相关属性,如设置字体、文字颜色等;在此,attributes中,只有NSFontAttributeName、NSForegroundColorAttributeName、NSBackgroundColorAttributeName有效
  133. - (void)setFunctionButtonTitleTextAttributes:(nullable NSDictionary *)attributes forState:(UIControlState)state;
  134. /* 1.让跟踪器时刻跟随外界scrollView滑动,实现了让跟踪器的宽度逐渐适应item宽度的功能;
  135. 2.这个方法用于外界的scrollViewDidScroll代理方法中,如
  136. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  137. [self.pageMenu moveTrackerFollowScrollView:scrollView];
  138. }
  139. 3.如果外界设置了SPPageMenu的属性"bridgeScrollView",那么外界就可以不用在scrollViewDidScroll方法中调用这个方法来实现跟踪器时刻跟随外界scrollView的效果,内部会自动处理; 外界对SPPageMenu的属性"bridgeScrollView"赋值是实现此效果的最简便的操作
  140. 4.如果不想要此效果,可设置closeTrackerFollowingMode==YES
  141. */
  142. - (void)moveTrackerFollowScrollView:(UIScrollView *)scrollView;
  143. // -------------- 以下方法和属性被废弃 --------------
  144. // 设置指定item的四周内边距,3.0版本的时候不小心多写了一个for,3.4.0版本已纠正
  145. - (void)setContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets forForItemAtIndex:(NSUInteger)itemIndex NS_DEPRECATED_IOS(6_0, 6_0, "Use -setContentEdgeInsets:forItemAtIndex:");
  146. // 默认NO;关闭跟踪器的跟随效果,在外界传了scrollView进来或者调用了moveTrackerFollowScrollView的情况下,如果为YES,则当外界滑动scrollView时,跟踪器不会时刻跟随,只有滑动结束才会跟随; 3.4.0版本开始被废弃,但是依然能使用,使用后相当于设置了SPPageMenuTrackerFollowingModeEnd枚举值
  147. @property (nonatomic, assign) BOOL closeTrackerFollowingMode NS_DEPRECATED_IOS(6_0, 6_0,"Use trackerFollowingMode instead");
  148. // 以下2个方法从3.0版本开始有升级,可以使用但不推荐
  149. - (void)setTitle:(nullable NSString *)title image:(nullable UIImage *)image imagePosition:(SPItemImagePosition)imagePosition imageRatio:(CGFloat)ratio forItemIndex:(NSUInteger)itemIndex NS_DEPRECATED_IOS(6_0, 6_0, "Use -setTitle:image:imagePosition:imageRatio:imageTitleSpace:forItemIndex:");
  150. - (void)setFunctionButtonTitle:(nullable NSString *)title image:(nullable UIImage *)image imagePosition:(SPItemImagePosition)imagePosition imageRatio:(CGFloat)ratio forState:(UIControlState)state NS_DEPRECATED_IOS(6_0, 6_0, "Use -setFunctionButtonTitle:image:imagePosition:imageRatio:imageTitleSpace:forState:");
  151. @end
  152. NS_ASSUME_NONNULL_END