需求分析:
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