目录
- 示例
ZYTYDataMainViewController : WMPageController
/**
菜单项
*/
@property (nonatomic,copy) NSArray *itemArr;
-(void)setupWM{
// 缓存机制
[self setCachePolicy:WMPageControllerCachePolicyBalanced];
// 下划线
self.progressWidth = 27;
self.progressColor=[UIColor whiteColor];
self.progressViewBottomSpace = 7;
self.progressHeight=3;
self.progressViewIsNaughty = YES;
// 菜单栏
self.menuViewStyle = WMMenuViewStyleLine;
self.titleFontName = @".PingFang-SC-Regular";
self.titleFontNameSelected = @".PingFang-SC-Bold";
self.titleColorNormal = [UIColor whiteColor];
self.titleColorSelected = [UIColor whiteColor];
self.titleSizeNormal = 15;
self.titleSizeSelected = 17;
[self reloadData]; // 必须+(刷新)
}
#pragma mark
- (NSInteger)numbersOfChildControllersInPageController:(WMPageController *)pageController {
return self.itemArr.count;
}
- (NSString *)pageController:(WMPageController *)pageController titleAtIndex:(NSInteger)index {
ZYDataMenuItemModel *itemM=self.itemArr[index];
return itemM.itemName;
}
- (UIViewController *)pageController:(WMPageController *)pageController viewControllerAtIndex:(NSInteger)index {
ZYDataMenuItemModel *itemM=self.itemArr[index];
ZYTYDataSecViewController *secVC=[ZYTYDataSecViewController new];
[secVC setPageType:itemM.matchType];
return secVC;
}
- (CGFloat)menuView:(WMMenuView *)menu widthForItemAtIndex:(NSInteger)index {
CGFloat width = [super menuView:menu widthForItemAtIndex:index];
return width-13;
}
- (CGRect)pageController:(WMPageController *)pageController preferredFrameForMenuView:(WMMenuView *)menuView {
return CGRectMake(8, kStatusBarHeight, kScreenWidth-45, 44);
}
- (CGRect)pageController:(WMPageController *)pageController preferredFrameForContentView:(WMScrollView *)contentView {
CGFloat originY = CGRectGetMaxY([self pageController:pageController preferredFrameForMenuView:self.menuView]);
return CGRectMake(0, originY, kScreenWidth, kScreenHeight - originY -kTabBarHeight);
}
- (void)menuView:(WMMenuView *)menu didSelectedIndex:(NSInteger)index currentIndex:(NSInteger)currentIndex{
[super menuView:menu didSelectedIndex:index currentIndex:currentIndex];
}
#pragma mark 懒加载
-(NSArray *)itemArr{
if(!_itemArr){
NSArray *itemArr=@[@[@"英超",@(0)],@[@"欧冠",@(0)],@[@"西甲",@(0)],@[@"德甲",@(0)],@[@"亚洲杯",@(1)],@[@"中超",@(0)],@[@"欧联",@(0)]];
NSMutableArray *tmpMuArr=[NSMutableArray arrayWithCapacity:10];
for(int i=0;i<itemArr.count;i++){
ZYDataMenuItemModel *item=[ZYDataMenuItemModel new];
[item setItemName:itemArr[i][0]];
[item setMatchType:[itemArr[i][1] intValue]];
[tmpMuArr addObject:item];
}
_itemArr=[tmpMuArr copy];
}
return _itemArr;
}
WMPageController
@interface WMPageController : UIViewController <WMMenuViewDelegate, WMMenuViewDataSource, UIScrollViewDelegate, WMPageControllerDataSource, WMPageControllerDelegate>
/**
缓存的机制
WMPageControllerCachePolicyDisabled = -1, // 禁用缓存
WMPageControllerCachePolicyNoLimit = 0, // 默认为无限制 (如果收到内存警告, 会自动切换)
WMPageControllerCachePolicyLowMemory = 1, // Low Memory but may block when scroll
WMPageControllerCachePolicyBalanced = 3, // Balanced ↑ and ↓ (建议设置)
WMPageControllerCachePolicyHigh = 5 // High
*/
@property (nonatomic, assign) WMPageControllerCachePolicy cachePolicy;
/**
预加载机制
在停止滑动的时候预加载 n 页
WMPageControllerPreloadPolicyNever = 0, // 从不预加载
WMPageControllerPreloadPolicyNeighbour = 1, // 预加载下一页.
WMPageControllerPreloadPolicyNear = 2 // 预加载相邻页.
*/
@property (nonatomic, assign) WMPageControllerPreloadPolicy preloadPolicy;
/**
dele、dataSource
*/
@property (nonatomic, weak) id<WMPageControllerDelegate> delegate;
@property (nonatomic, weak) id<WMPageControllerDataSource> dataSource;
/**
menuView菜单项视图
*/
@property (nonatomic, nullable, weak) WMMenuView *menuView;
/**
scrollView内容视图
*/
@property (nonatomic, nullable, weak) WMScrollView *scrollView;
/**
当前ViewController(只读)
*/
@property (nonatomic, strong, readonly) UIViewController *currentViewController;
/**
标题数组
*/
@property (nonatomic, nullable, copy) NSArray<NSString *> *titles;
/**
子控制数组
*/
@property (nonatomic, nullable, copy) NSArray<Class> *viewControllerClasses;
/**
下标
*/
@property (nonatomic, assign) int selectIndex;
/**
子控制是否可滚动
*/
@property (nonatomic, assign) BOOL scrollEnable;
/**
子控制器是否动画滚动
*/
@property (nonatomic, assign) BOOL pageAnimatable;
/**
内容视图bounces弹性
*/
@property (nonatomic, assign) BOOL bounces;
//------------------------------- MenuView ---------------------------------
/**
menuViewStyle
WMMenuViewStyleDefault, // 默认
WMMenuViewStyleLine, // 带下划线 (若要选中字体大小不变,设置选中和非选中大小一样即可)
WMMenuViewStyleTriangle, // 三角形 (progressHeight 为三角形的高, progressWidths 为底边长)
WMMenuViewStyleFlood, // 涌入效果 (填充)
WMMenuViewStyleFloodHollow, // 涌入效果 (空心的)
WMMenuViewStyleSegmented, // 涌入带边框,即网易新闻选项卡
*/
@property (nonatomic, assign) WMMenuViewStyle menuViewStyle;
/**
menuView布局
WMMenuViewLayoutModeScatter, // 默认的布局模式, item 会均匀分布在屏幕上,呈分散状
WMMenuViewLayoutModeLeft, // Item 紧靠屏幕左侧
WMMenuViewLayoutModeRight, // Item 紧靠屏幕右侧
WMMenuViewLayoutModeCenter, // Item 紧挨且居中分布
*/
@property (nonatomic, assign) WMMenuViewLayoutMode menuViewLayoutMode;
/**
MenuView总视图左右的间距
*/
@property (nonatomic, assign) CGFloat menuViewContentMargin;
/**
MenuView是否作为 NavigationBar 的 titleView 展示,
默认 NO
*/
@property (assign, nonatomic) BOOL showOnNavigationBar;
//------------------------------- MenuView标题 ---------------------------------
/**
未选中 标题字体大小
*/
@property (nonatomic, assign) CGFloat titleSizeNormal;
/**
选中 标题字体大小
*/
@property (nonatomic, assign) CGFloat titleSizeSelected;
/**
未选中 标题字体名
*/
@property (nonatomic, nullable, copy) NSString *titleFontName;
/**
选中 标题字体名
*/
@property (nonatomic, nullable, copy) NSString *titleFontNameSelected;
/**
未选中 标题颜色
*/
@property (nonatomic, strong) UIColor *titleColorNormal;
/**
选中 标题颜色
*/
@property (nonatomic, strong) UIColor *titleColorSelected;
/**
标题宽度
*/
@property (nonatomic, assign) CGFloat menuItemWidth;
/**
标题宽度数组
*/
@property (nonatomic, nullable, copy) NSArray<NSNumber *> *itemsWidths;
/**
是否自动通过字符串计算标题宽度,
默认为 NO
*/
@property (nonatomic, assign) BOOL automaticallyCalculatesItemWidths;
/**
标题相同间隙
*/
@property (nonatomic, assign) CGFloat itemMargin;
/**
标题间隙
包括头尾两端,所以确保它的数量等于控制器数量 + 1, 默认间隙为 0
*/
@property (nonatomic, nullable, copy) NSArray<NSNumber *> *itemsMargins;
/**
下划线颜色
*/
@property (nonatomic, strong) UIColor *lineColor;
//------------------------------- 下划线 ---------------------------------
/**
progressView的颜色
默认和选中颜色一致(如果 style 为 Default,则该属性无用)
*/
@property (nonatomic, nullable, strong) UIColor *progressColor;
/**
progressView的宽度(相同宽度)
*/
@property (nonatomic, assign) CGFloat progressWidth;
/**
progressView的宽度数组
*/
@property (nonatomic, nullable, strong) NSArray *progressViewWidths;
/**
progressView的高度
*/
@property (nonatomic, assign) CGFloat progressHeight;
/**
progressView 到 menuView 底部的距离
*/
@property (nonatomic, assign) CGFloat progressViewBottomSpace;
/**
progressView的圆角
*/
@property (nonatomic, assign) CGFloat progressViewCornerRadius;
/**
调皮效果,用于实现腾讯视频新效果,请设置一个较小的 progressWidth
*/
@property (nonatomic, assign) BOOL progressViewIsNaughty;
//------------------------------- 其他属性 ---------------------------------
/**
values keys 属性可以用于初始化控制器的时候为控制器传值(利用 KVC 来设置)
使用时请确保 key 与控制器的属性名字一致!!(例如:控制器有需要设置的属性 type,那么 keys 所放的就是字符串 @"type")
*/
@property (nonatomic, nullable, strong) NSMutableArray<id> *values;
@property (nonatomic, nullable, strong) NSMutableArray<NSString *> *keys;
/**
是否发送在创建控制器或者视图完全展现在用户眼前时通知观察者,默认为不开启,如需利用通知请开启
*/
@property (nonatomic, assign) BOOL postNotification;
/**
用代码设置 contentView 的 contentOffset 之前,请设置 startDragging = YES
*/
@property (nonatomic, assign) BOOL startDragging;
//------------------------------- 方法 ---------------------------------
/**
需要更新时调用
*/
- (void)reloadData;
/**
强制重新布局
会调用`-pageController:preferredFrameForContentView:` and `-pageContoller:preferredFrameForMenuView:`
*/
- (void)forceLayoutSubviews;
/**
更新指定index的标题内容
@param title 新标题
@param index index下标
*/
- (void)updateTitle:(NSString *)title atIndex:(NSInteger)index;
/**
更新指定index的标题内容、宽
@param title 新标题
@param width 宽
@param index index下标
*/
- (void)updateTitle:(NSString *)title andWidth:(CGFloat)width atIndex:(NSInteger)index;
/**
更新指定index的复杂标题
@param title 新标题
@param index index下标
*/
- (void)updateAttributeTitle:(NSAttributedString *)title atIndex:(NSInteger)index;
/**
即将进入后台时调用(覆写)
@param notification 通知
*/
- (void)willResignActive:(NSNotification *)notification;
/**
即将回到前台时调用(覆写)
@param notification 通知
*/
- (void)willEnterForeground:(NSNotification *)notification;
/**
构造方法
@param classes 子控制器数组
@param titles 标题数组
@return 实例
*/
- (instancetype)initWithViewControllerClasses:(NSArray<Class> *)classes andTheirTitles:(NSArray<NSString *> *)titles;
@end
WMPageControllerDataSource 协议
@protocol WMPageControllerDataSource <NSObject>
@optional
/**
子控制器的数量
@param pageController pageController
@return 子控制器的数量
*/
- (NSInteger)numbersOfChildControllersInPageController:(WMPageController *)pageController;
/**
index对应的子控制
@param pageController pageController
@param index index
@return index对应的子控制
*/
- (__kindof UIViewController *)pageController:(WMPageController *)pageController viewControllerAtIndex:(NSInteger)index;
/**
index对应的标题
@param pageController pageController
@param index index
@return index对应的标题
*/
- (NSString *)pageController:(WMPageController *)pageController titleAtIndex:(NSInteger)index;
@required
/**
内容视图的frame
@param pageController pageController
@param contentView contentView
@return 内容视图的frame
*/
- (CGRect)pageController:(WMPageController *)pageController preferredFrameForContentView:(WMScrollView *)contentView;
/**
Implement this datasource method, in order to customize your own menuView's frame
@param pageController The container controller
@param menuView The menuView
@return The frame of the menuView
*/
/**
菜单项视图的frame
@param pageController pageController
@param menuView menuView
@return 菜单项视图的frame
*/
- (CGRect)pageController:(WMPageController *)pageController preferredFrameForMenuView:(WMMenuView *)menuView;
@end
WMPageControllerDelegate 协议
@protocol WMPageControllerDelegate <NSObject>
@optional
/**
懒加载,只有在初始化控制器并停止滚动时才会调用此方法。
这意味着如果控制器被缓存并且没有释放,则永远不会调用此方法
@param pageController pageController
@param viewController viewController
@param info 包含index、title
*/
- (void)pageController:(WMPageController *)pageController lazyLoadViewController:(__kindof UIViewController *)viewController withInfo:(NSDictionary *)info;
/**
viewController被缓存时调用
@param pageController pageController
@param viewController viewController
@param info 包含index、title
*/
- (void)pageController:(WMPageController *)pageController willCachedViewController:(__kindof UIViewController *)viewController withInfo:(NSDictionary *)info;
/**
viewController即将显示时调用
@param pageController pageController
@param viewController 即将显示的viewController
@param info 包含index、title
*/
- (void)pageController:(WMPageController *)pageController willEnterViewController:(__kindof UIViewController *)viewController withInfo:(NSDictionary *)info;
/**
内容视图完全停止滚动时调用(viewController完全显示在用户面前)
@param pageController pageController
@param viewController 即将显示的viewController
@param info 包含index、title
*/
- (void)pageController:(WMPageController *)pageController didEnterViewController:(__kindof UIViewController *)viewController withInfo:(NSDictionary *)info;
@end
WMMenuViewDataSource 协议
@protocol WMMenuViewDataSource <NSObject>
@required
/**
菜单项个数
@param menu WMMenuView
@return 菜单项个数
*/
- (NSInteger)numbersOfTitlesInMenuView:(WMMenuView *)menu;
/**
index对应的菜单项标题
@param menu WMMenuView
@param index index
@return index对应的菜单项标题
*/
- (NSString *)menuView:(WMMenuView *)menu titleAtIndex:(NSInteger)index;
@optional
/**
* 角标 (例如消息提醒的小红点) 的数据源方法,在 WMPageController 中实现这个方法来为 menuView 提供一个 badgeView
需要在返回的时候同时设置角标的 frame 属性,该 frame 为相对于 menuItem 的位置
*
* @param index 角标的序号
*
* @return 返回一个设置好 frame 的角标视图
*/
/**
index对应的角标视图(设置好frame)
@param menu WMMenuView
@param index index
@return index对应的角标视图(设置好frame)
*/
- (UIView *)menuView:(WMMenuView *)menu badgeViewAtIndex:(NSInteger)index;
/**
定制菜单项
此时的 WMMenuView、item 的 frame 是不确定的,所以请勿根据此时的 frame 做计算!
@param menu WMMenuView
@param initialMenuItem 原始菜单项(做修改,或返回自定义子类)
@param index index
@return 定制菜单项
*/
- (WMMenuItem *)menuView:(WMMenuView *)menu initialMenuItem:(WMMenuItem *)initialMenuItem atIndex:(NSInteger)index;
@end
WMMenuViewDelegate 协议
@protocol WMMenuViewDelegate <NSObject>
@optional
/**
是否允许选中
@param menu WMMenuView
@param index 将要选中的index
@return 是否允许选中
*/
- (BOOL)menuView:(WMMenuView *)menu shouldSelesctedIndex:(NSInteger)index;
/**
选中后调用
@param menu WMMenuView
@param index 将要选中的index
@param currentIndex 当前index
*/
- (void)menuView:(WMMenuView *)menu didSelesctedIndex:(NSInteger)index currentIndex:(NSInteger)currentIndex;
/**
index对应的菜单项宽
@param menu WMMenuView
@param index index
@return index对应的菜单项宽
*/
- (CGFloat)menuView:(WMMenuView *)menu widthForItemAtIndex:(NSInteger)index;
/**
index对应的菜单项Margin
@param menu WMMenuView
@param index index
@return index对应的菜单项Margin
*/
- (CGFloat)menuView:(WMMenuView *)menu itemMarginAtIndex:(NSInteger)index;
/**
index对应不同状态的菜单项宽
@param menu WMMenuView
@param state WMMenuItemState
@param index index
@return index对应不同状态的菜单项宽
*/
- (CGFloat)menuView:(WMMenuView *)menu titleSizeForState:(WMMenuItemState)state atIndex:(NSInteger)index;
/**
index对应不同状态的菜单项颜色
@param menu WMMenuView
@param state WMMenuItemState
@param index index
@return index对应不同状态的菜单项颜色
*/
- (UIColor *)menuView:(WMMenuView *)menu titleColorForState:(WMMenuItemState)state atIndex:(NSInteger)index;
/**
重新布局后调用
@param menu WMMenuView
@param menuItem 菜单项
@param index index
*/
- (void)menuView:(WMMenuView *)menu didLayoutItemFrame:(WMMenuItem *)menuItem atIndex:(NSInteger)index;
@end
网友评论