美文网首页iOS开发之笔记摘录
多页面嵌套(WMPageController)

多页面嵌套(WMPageController)

作者: 平安喜乐698 | 来源:发表于2019-03-13 19:14 被阅读5次
    目录
    
    
    1. 示例
    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
    

    相关文章

      网友评论

        本文标题:多页面嵌套(WMPageController)

        本文链接:https://www.haomeiwen.com/subject/vmgtmqtx.html