iOS开发之笔记摘录

多页面嵌套(WMPageController)

2019-03-13  本文已影响5人  平安喜乐698
目录

  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
上一篇 下一篇

猜你喜欢

热点阅读