2013-04-06 53 views
1

我創建了一個UITableView,其中包含自定義部分標題視圖。現在,我希望它在最上面的當前可見部分顯示更多的數據。我打算使用事件scrollViewDidEndDecelerating更新節標題。目前,問題是我無法爲特定節號設置節標題高度。調整tableview的第一個可見部分標題高度

我曾嘗試使用heightForHeaderInSection事前,但應用程序只是下面的輸出崩潰:

'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

我用的是代碼:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    if (tableView == self.tableView) 
    { 
     NSArray *visibleCells = [self.tableView visibleCells]; 
     NSMutableArray *visibleSections = [[NSMutableArray alloc] init]; 
     for (NSInteger index = 0; index < [visibleCells count]; index++) 
     { 
      UITableViewCell *currentCell = [visibleCells objectAtIndex:index]; 
      NSIndexPath *currentPath = (NSIndexPath *)[self.tableView indexPathForCell:currentCell]; 
      if (![visibleSections containsObject:[NSNumber numberWithInt:currentPath.section]]) 
      { 
       [visibleSections addObject:[NSNumber numberWithInt:currentPath.section]]; 
       NSLog([NSString stringWithFormat:@"%ld", (long)[visibleSections count]]); 
       [visibleSections sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:nil ascending:YES]]]; 
      } 
     } 
     if (visibleSections == nil) 
     { 
      return 42.0; 
     } 
     else if ([[visibleSections objectAtIndex:0] integerValue] == section) 
     { 
      return 58.0; 
     } 
     else 
     { 
      return 42.0; 
     } 
    } 
} 

我不能完全從工作我的heightForHeaderInSection方法出了什麼問題,但我知道它與NSMutableArray,visibleSections有關。

任何關於如何改變heightForHeaderInSection以外的特定區域標題視圖的高度和/或如何修復上面的代碼的提示或答案都是非常有用的。

編輯:

只是爲了解決我的問題,崩潰有點更清晰,if (visibleSections == nil)不應代替if ([visibleSections count] < 1)if ([visibleSections count] == 0)使用。

+0

是什麼您登錄的[visibleSection計數]說明了什麼? – rdelmar 2013-04-06 16:59:17

+0

@rdelmar它只是將日誌編輯爲第6行之後,並輸出零。我猜測即使應用程序沒有顯示內容,代碼也會啓動。 – 2013-04-06 17:04:01

+0

@rdelmar但我很困惑,爲什麼它甚至會輸出錯誤,當它甚至不會被使用,如果它是空的。 – 2013-04-06 17:07:26

回答

0

好吧,事實證明這是一個比看起來更難的問題。到目前爲止我所得到的最好的結果是

  • 不要將頂部的頭部視爲任何不同,並用額外的數據填充它們。
  • 您可以通過巧妙地定位「附加」項目來顯示和隱藏不同的部分,以便在較小的父視圖邊界之外並使父視圖clipToBounds位於父視圖的邊界之外。
  • 如果做不到這一點,你可以做一個自定義的UIView子類,並做一些操縱layoutSubviews

最終實現我解決的是這個

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    NSArray *indexPaths = [self.tableView indexPathsForVisibleRows]; 
    self.topSection = [indexPaths count] ? [indexPaths[0] section] : -1; 
    if (indexPaths.count > 1) { 
    self.topSection = [indexPaths[1] section]; 
    } 

    [self.tableView beginUpdates]; 
    [self.tableView endUpdates]; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; 
{ 
    if (section <= self.topSection) { 
    return 60; 
    } else { 
    return 20; 
    } 
} 

這絕不是完美的,但它看上去半合理並可以調整。

注意事項:

  • 您可能需要評估,如果有太多的工作要在scrollViewDidScroll:,但它似乎沒有引起我任何滯後(我沒有真正的考驗正確)
  • 我是否可以使用第二indexPath設置的頂部,因爲它看起來稍微更加賞心悅目/少笨重
  • 我用section <= self.topSection,因爲頭的前全屏幕所以在減少它們的尺寸不會引起點真的很笨重的動畫。

所以嘗試此方法後,您可能需要深入瞭解或者想重新考慮你的設計有點

+0

這可以很好地工作,但我使用半透明漸變作爲我的部分標題,它擴展到標題視圖之外。我想我必須稍微調整一下設計。 – 2013-04-07 10:03:08

+0

那麼你可以讓headerView成爲一個自定義的子類,然後你應該能夠找到一個合適的點來請求視圖重繪它的漸變 – 2013-04-07 10:07:00

-1

嘗試修改此行:

NSMutableArray *visibleSections = [[NSMutableArray alloc] init] 

到:

NSMutableArray *visibleSections = [NSMutableArray array]; 

用於初始化數組。

+0

這兩個陳述基本上是相同的。 – rdelmar 2013-04-06 17:03:53

+1

*兩個語句都初始化數組。*唯一的區別是第一個方法返回一個(+1)保留對象,第二個方法不返回。用ARC,你根本不會注意到這個差別。 – 2013-04-06 17:04:11

0

你不能直接引用數組第一個對象,通過調用objectAtIndex:0,你要保持防守如此改變這一點:

else if ([[visibleSections objectAtIndex:0] integerValue] == section) 
    { 
     return 58.0; 
    } 

else if([visibleSections count]>0) 
    { 
     if ([[visibleSections objectAtIndex:0] integerValue] == section) 
     { 
      return 58.0; 
     } 
    } 
+0

謝謝,這解決了崩潰問題,但它仍然沒有按照我希望的方式執行。如果必須的話,我會調查併發布另一個問題。 順便說一句,我只是用'if([visibleSections count] <1)'來避免寫更多的行。 – 2013-04-06 17:14:06

+0

爲什麼接受的答案是實際上並未編譯的答案? - 可能是所使用格式不佳的一個副作用......「if」塊中有一個不必要的'else' – 2013-04-06 17:50:34

+0

@ Paul.s對不起,這是一個錯字。 – satheeshwaran 2013-04-06 17:52:48

1

我想你也可以做到這一點像這個,如果你希望當表第一次出現(topSection是一個NSInteger屬性)時第一個部分頭部更高:

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    self.topSection = ((NSIndexPath *)[self.tableView indexPathsForVisibleRows][0]).section; 
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:self.topSection] withRowAnimation:NO]; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 

     if (self.topSection == section) 
     { 
      return 58.0; 
     } 
     else 
     { 
      return 42.0; 
     } 
} 
+0

+1,但是在'tableView:heightForHeaderInSection:'方法中使用'topSection'查詢會更好嗎? – 2013-04-06 18:12:47

+0

@ Paul.s,我先試了一下,結果崩潰了。它似乎陷入了無限循環。不知道爲什麼。 – rdelmar 2013-04-06 18:14:18

+0

這很好用。我已經標記爲答案。 **編輯:**我也改變了標題更準確。 – 2013-04-06 18:18:33

相關問題