用過了那麼多的外賣App,總結出一個規律,那就是「全部的外賣App都有雙列表聯動功能」。哈哈哈哈,這是一個玩笑。git
此次我也須要開發具備聯動效果的雙列表。也是首次開發這種類型的UI,記錄下步驟與心得github
#pragma mark -- UITableViewDelegate -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ if (tableView == self.leftTablview) { return 1; } return self.datas.count; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if (tableView == self.leftTablview) { return self.datas.count; } QuestionCollectionModel *model = self.datas[section]; NSArray *questions =model.questions; return questions.count; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == self.leftTablview) { return LeftCellHeight; } return RightCellHeight; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == self.leftTablview) { PregnancyPeriodCell *cell = [tableView dequeueReusableCellWithIdentifier:PregnancyPeriodCellID forIndexPath:indexPath]; if (self.collectionType == CollectionType_Wrong || self.collectionType == CollectionType_Miss) { QuestionCollectionModel *model = self.datas[indexPath.row]; cell.week = model.tag; } return cell; } QuestionCell *cell = [tableView dequeueReusableCellWithIdentifier:QuestionCellID forIndexPath:indexPath]; QuestionCollectionModel *model = self.datas[indexPath.section]; NSArray *questions =model.questions; QuestionModel *questionModel = questions[indexPath.row]; cell.model = questionModel; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == self.leftTablview) { NSIndexPath *indexpath = [NSIndexPath indexPathForRow:0 inSection:indexPath.row]; [self.rightTableview scrollToRowAtIndexPath:indexpath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } } -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ if (scrollView == self.rightTableview) { NSIndexPath *indexpath = [self.rightTableview indexPathsForVisibleRows].firstObject; NSIndexPath *leftScrollIndexpath = [NSIndexPath indexPathForRow:indexpath.section inSection:0]; [self.leftTablview selectRowAtIndexPath:leftScrollIndexpath animated:YES scrollPosition:UITableViewScrollPositionMiddle]; } }
缺陷:雖然實現了效果,可是有缺陷。點擊左側的UITableView,右側的UITableViewe滾動到相應的位置,這是沒問題的,可是滾動代理
右邊,須要根據右邊indexPath.section將選中左側相應的indexPath。這樣左側選中的時候,又會觸發右邊滾動的事件,總體看上去不是很流暢。code
觀察了下,發現右側滾動的時候左側會上下選中,因此也就是隻要讓右側滾動的時候,左側的UITableView單方向選中,不要滾動就好,因此因爲UITableView也是UIScrollview,因此在scrollViewDidScroll方法中判斷右側的UITableView是向上仍是向下滾動,以此做爲判斷條件來讓左側的UITableView選中相應的行。事件
且以前是在scrollview代理方法中讓左側的tableview選中,這樣子又會觸發左側tableview的選中事件,從而致使右側的tablview滾動,形成不嚴謹的聯動邏輯開發
改進後的方法:get
[self.rightTableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] atScrollPosition:UITableViewScrollPositionTop animated:YES];
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == self.rightTableview && !self.isScrollDown && self.rightTableview.isDragging ) { [self.leftTablview selectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.section inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop]; } } -(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == self.rightTableview && self.isScrollDown && self.rightTableview.isDragging) { [self.leftTablview selectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.section+1 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop]; } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath { if (self.leftTablview == tableView) { [self.rightTableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.row] atScrollPosition:UITableViewScrollPositionTop animated:YES]; }else{ NSLog(@"嗡嗡嗡"); } } #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ static CGFloat lastOffsetY = 0; UITableView *tableView = (UITableView *)scrollView; if (self.rightTableview == tableView){ self.isScrollDown = (lastOffsetY < scrollView.contentOffset.y); lastOffsetY = scrollView.contentOffset.y; } }
附上Demo:Demoit