IOS 类似网易新闻客户端内容滚动菜单跟随居中组件
需求分析:
1、类似网易新闻客户端页面滚动组件、菜单栏对应菜单项一直居中
2、点击菜单栏可以切换到对应的page
3、滑动页面可以自动切换相应的菜单、并且对应的菜单栏居中显示
4、初始化时可以自定义菜单项
5、菜单内容、页面内容自定义
设计实现:
1、菜单和页面内容分别设计为两个横向滚动的UITableView,将两个横向滚动的tableView 放置在一个UIView中
2、点击菜单栏时响应该事件,并将页面切换到响应页
3、内容页面滚动停止时,将对应菜单项滚动到中间
实现效果:
四、关键代码
1、横向的tableview 如何实现
- (UITableView *)topMenuTableView { if(nil == _topMenuTableView) { CGFloat topMenuHeight = TopTabControl_Default_TopMenuHeight; if([self.datasource respondsToSelector:@selector(TopTabHeight:)]) { topMenuHeight = [self.datasource TopTabHeight:self]; } //before rotate bounds = (0, 0, width, height) , rototate -90 bounds = (0, 0, height, width) CGFloat x = CGRectGetWidth(self.frame)/2 - topMenuHeight/2; CGFloat y = -CGRectGetWidth(self.frame)/2 + topMenuHeight/2; CGRect topMenuRect = CGRectMake(x, y, topMenuHeight, CGRectGetWidth(self.frame)); _topMenuTableView = [[UITableView alloc] initWithFrame:topMenuRect style:UITableViewStylePlain]; [self addSubview:_topMenuTableView]; _topMenuTableView.backgroundColor = [UIColor randomColor]; _topMenuTableView.dataSource = self; _topMenuTableView.delegate = self; _topMenuTableView.showsVerticalScrollIndicator = NO; _topMenuTableView.transform = CGAffineTransformMakeRotation(-M_PI / 2); } return _topMenuTableView; } - (UITableView *)contentTableView { if(nil == _contentTableView) { CGFloat contentHeight = CGRectGetWidth(self.frame); CGFloat contentWidth = CGRectGetHeight(self.frame) - [self getMenuHeight]; CGFloat x = CGRectGetWidth(self.frame)/2 - contentWidth/2; CGFloat y = (CGRectGetHeight(self.frame) - [self getMenuHeight])/2 - contentHeight/2 + ([self getMenuHeight]); CGRect contentRect = CGRectMake(x, y, contentWidth, contentHeight); _contentTableView = [[UITableView alloc] initWithFrame:contentRect style:UITableViewStylePlain]; [self addSubview:_contentTableView]; _contentTableView.backgroundColor = [UIColor randomColor]; _contentTableView.dataSource = self; _contentTableView.delegate = self; _contentTableView.showsVerticalScrollIndicator = NO; _contentTableView.pagingEnabled = YES; _contentTableView.transform = CGAffineTransformMakeRotation(-M_PI / 2); } return _contentTableView; }
2、协议接口
/** @brief TopTabControl datasource 需要支持的协议 */ @protocol TopTabControlDataSource<NSObject> @optional /** * 得到顶部菜单栏的高度 * * @param tabCtrl tab控件 * * @return 高度(像素) */ - (CGFloat)TopTabHeight:(TopTabControl *)tabCtrl; /** * 得到顶部菜单栏的宽度 * * @param tabCtrl tab控件 * * @return 高度(像素) */ - (CGFloat)TopTabWidth:(TopTabControl *)tabCtrl; /** * 得到顶部菜单的个数 * * @param tabCtrl tab控件 * * @return 返回菜单的个数 */ - (NSInteger)TopTabMenuCount:(TopTabControl *)tabCtrl; /** * 得到第几个菜单的view * * @param tabCtrl tab控件 * @param index 菜单的index,从0开始 * * @return 返回单个菜单项 */ - (TopTabMenuItem *)TopTabControl:(TopTabControl *)tabCtrl itemAtIndex:(NSUInteger)index; /** * 得到第几个菜单对应的page内容 * * @param tabCtrl tab控件 * @param index 菜单的index,从0开始 * * @return 返回单个菜单页 */ - (TopTabPage *)TopTabControl:(TopTabControl *)tabCtrl pageAtIndex:(NSUInteger)index; @end
五、完整代码
https://github.com/liqiushui/TopTabControl