2009-07-02 47 views
120

我正在使用UITableView來佈置內容'網頁'。我使用表視圖的標題來佈局某些圖像等,如果它們沒有浮動但是保持靜態,就像樣式設置爲時那樣,我更喜歡它。是否可以通過UITableViewStylePlain在UITableView中禁用浮動標題?

其他然後使用,有沒有辦法做到這一點?我想避免使用分組,因爲它會在我的所有單元格中添加邊距,並且需要禁用每個單元格的背景視圖。我想完全控制我的佈局。理想情況下,他們會是一個「UITableViewStyleBareBones」,但我沒有看到文檔該選項...

非常感謝,

回答

23

您應該可以通過使用自定義單元格來完成您的標題行。這些將像表格視圖中的其他單元格一樣滾動。

您只需在cellForRowAtIndexPath中添加一些邏輯即可在標題行中返回正確的單元格類型。

雖然您可能必須自己管理自己的部分,即將所有內容都放在一個部分中並假冒標題。 (您也可以嘗試爲標題視圖返回隱藏視圖,但我不知道這是否可行)

+9

是啊...它似乎有點黑客。這看起來像是一個蘋果公司的一部分,顯然代碼是在那裏做的,我們只需要能夠設置一個標誌。 – Tricky 2009-07-02 13:54:26

-4

您可以輕鬆地在實現代碼如下委託類實現viewForHeaderInSection方法實現這一目標。這個方法需要一個UIView作爲返回對象(這是你的標題視圖)。我在我的代碼中做了同樣的事情

+0

我也做到了這一點,當您滾動時,返回的視圖仍然浮動... – Tricky 2009-07-02 12:31:20

+0

原始海報不需要自定義標題。他們想要一個不會「浮動」在表格頂部的標題。你的建議仍然浮動。 – jemmons 2010-07-19 00:05:03

60

警告:此解決方案實現了預留的API方法。這可能會阻止該應用程序被蘋果批准在AppStore上發佈。

我所描述的私有方法節頭浮在my blog

基本的,輪流,你只需要繼承UITableView和它的兩個方法返回NO

- (BOOL)allowsHeaderViewsToFloat; 
- (BOOL)allowsFooterViewsToFloat; 
+27

僅僅因爲它引用了私有API(不是每個人都在編寫要提交給AppStore的代碼),答案都不值得讚賞。當答案正確時,這是雙重的。爲這些方法返回NO的子類化(或者更簡單地說,創建一個UITableView類別)會阻止標頭浮動。 如果您希望將此功能添加爲公共API,請提交錯誤報告:http://bugreport.apple.com – jemmons 2010-07-19 00:18:17

+4

如果我們在應用程序中實現該功能,蘋果如何意識到您正在使用私人API?從他們所知道的,我只是在UITableView的子類中實現了一個方法,他們甚至不需要拆卸代碼就看不到它,並且它不會那麼容易。它不是在私人API中調用方法,它只是實現一個... – 2012-01-25 19:46:53

0

忽略XAK。如果您希望自己的應用有機會被蘋果接受,請不要探索任何私人方法。

如果您使用Interface Builder,這是最容易的。你可以在視圖的頂部添加一個UIView(圖像將放在那裏),然後在下面添加你的tableview。 IB應相應地調整它的大小;也就是說,tableview的頂部會觸及剛剛添加的UIView的底部,並且它的高度覆蓋了屏幕的其餘部分。

這裏的想法是,如果該UIView實際上不是表視圖的一部分,它將不會與tableview一起滾動。即忽略tableview標題。

如果您不使用接口構建器,它會更復雜一點,因爲您必須爲tableview獲取正確的位置和高度。

+0

這不回答問題。 Tricky指的是titleHeaderViews,它是位於單元格之間的視圖,而不是表格標題視圖,這是您似乎暗示的。 – 2010-06-15 13:52:22

258

一個可能更容易的方式來實現這一目標:

的Objective-C:

CGFloat dummyViewHeight = 40; 
UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, dummyViewHeight)]; 
self.tableView.tableHeaderView = dummyView; 
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0); 

斯威夫特:

let dummyViewHeight = CGFloat(40) 
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight)) 
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0) 

節頭現在將滾動就像任何普通的細胞。

+4

這個friggin就像一個魅力!表格標題視圖標題的存在會停止浮動的章節標題。並且爲表格提供適當內容的無形標題可以做到這一點。非常感謝!想知道爲什麼這個答案沒有得到太多的關注 – 2012-06-11 11:45:57

+2

還是不信!沒有私人API,沒有深入課堂,沒有什麼!我一直在面對這個問題很長時間,並且一直在滾動視圖的頂部添加tableviews(禁用tableview滾動),這將使表格標題正常滾動。但剛開始搜索蘋果是否提供了新的方法來解決這個問題..很高興我偶然發現了你的答案。再次感謝 – 2012-06-11 11:53:57

+0

你用這件小事拯救了我的一天。按預期工作,不需要單行代碼。我很驚訝。謝謝你,先生! – 2012-09-12 20:48:49

16

關於UITableViewStyleGrouped有趣的是,tableView將樣式添加到單元格而不是TableView。

樣式作爲backgroundView添加到單元格中,作爲名爲UIGroupTableViewCellBackground的類,該類根據該部分中單元格的位置處理繪製不同背景。

所以有一個非常簡單的解決方案將是cellForRow使用UITableViewStyleGrouped,該表的backgroundColor設置爲clearColor,並且只需更換backgroundView細胞:

cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds] autorelease]; 
+1

這應該是最好的答案。這裏有一篇關於它的博客文章:http://corecocoa.wordpress.com/2011/09/17/how-to-disable-floating-header-in-uitableview/ – Sam 2012-03-28 14:05:27

+0

該解決方案實際上並不奏效。我一直在周圍的單元周圍獲得額外的空間。任何想法 ? – gsempe 2012-09-12 14:34:30

4

雖然這也許不能解決你的問題,當我想做類似的事情時,它爲我做了。而不是設置標題我使用了上面部分的頁腳。保存我的是,這部分本質上是小而靜的,所以它從來沒有滾動到視圖的底部。

+0

好主意。我喜歡這個黑客。 – 2012-01-31 21:21:20

+0

有點可笑。欣賞這個想法,但是黑客就是黑客。標題將在底部開始浮動,因此不能真正解決問題 – 2012-06-11 11:56:57

0

這可以通過在UITableViewController的viewDidLoad方法中手動分配標題視圖而不是使用委託的viewForHeaderInSection和heightForHeaderInSection來實現。例如,在您的UITableViewController的子類,你可以做這樣的事情:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    UILabel *headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 40)]; 
    [headerView setBackgroundColor:[UIColor magentaColor]]; 
    [headerView setTextAlignment:NSTextAlignmentCenter]; 
    [headerView setText:@"Hello World"]; 
    [[self tableView] setTableHeaderView:headerView]; 
} 

頭視圖將消失,然後當用戶滾動。我不知道爲什麼這樣工作,但它似乎達到了你想要做的。

28

好吧,我知道這是晚了,但我不得不這樣做。 我花了10個小時,現在正在尋找一個工作解決方案,但沒有找到完整的答案。發現了一些提示,但難以讓初學者理解。所以我必須投入2美分並完成答案。

正如我在少數答案中提出的那樣,我能夠實現的唯一工作解決方案是在表視圖中插入普通單元格並將它們作爲Section Headers來處理,但實現它的更好方法是通過將這些單元格插入每個部分的第0行。這樣我們就可以很容易地處理這些自定義的非浮動頭文件。

所以,步驟是。

  1. 使用樣式UITableViewStylePlain實現UITableView。

    -(void) loadView 
    { 
        [super loadView]; 
    
        UITableView *tblView =[[UITableView alloc] initWithFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height-44-61-frame.origin.y) style:UITableViewStylePlain]; 
        tblView.delegate=self; 
        tblView.dataSource=self; 
        tblView.tag=2; 
        tblView.backgroundColor=[UIColor clearColor]; 
        tblView.separatorStyle = UITableViewCellSeparatorStyleNone; 
    } 
    
  2. 實現titleForHeaderInSection像往常一樣(你可以用自己的邏輯此值,但我更喜歡使用標準的代表)。

    - (NSString *)tableView: (UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
    { 
        NSString *headerTitle = [sectionArray objectAtIndex:section]; 
        return headerTitle; 
    } 
    
  3. Immplement numberOfSectionsInTableView照常

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    { 
        int sectionCount = [sectionArray count]; 
        return sectionCount; 
    } 
    
  4. 實施numberOfRowsInSection如常。

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    { 
        int rowCount = [[cellArray objectAtIndex:section] count]; 
        return rowCount +1; //+1 for the extra row which we will fake for the Section Header 
    } 
    
  5. 返回0.0f in heightForHeaderInSection。

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
    { 
        return 0.0f; 
    } 
    
  6. 請勿實施viewForHeaderInSection。完全移除該方法而不是返回nil。

  7. In heightForRowAtIndexPath。檢查是否(indexpath.row == 0)並返回節標題所需的單元格高度,否則返回單元格的高度。

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
        if(indexPath.row == 0) 
        { 
         return 80; //Height for the section header 
        } 
        else 
        { 
         return 70; //Height for the normal cell 
        } 
    } 
    
  8. 現在的cellForRowAtIndexPath,檢查(indexpath.row == 0),當你想要節頭是和選擇樣式設置爲none執行單元。 ELSE實現這個單元格就像你想要的正常單元格一樣。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
        if (indexPath.row == 0) 
        { 
         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SectionCell"]; 
         if (cell == nil) 
         { 
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SectionCell"] autorelease]; 
          cell.selectionStyle = UITableViewCellSelectionStyleNone; //So that the section header does not appear selected 
    
          cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SectionHeaderBackground"]]; 
         } 
    
         cell.textLabel.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:indexPath.section]; 
    
         return cell; 
        } 
        else 
        { 
         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 
    
         if (cell == nil) 
         { 
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease]; 
          cell.selectionStyle = UITableViewCellSelectionStyleGray; //So that the normal cell looks selected 
    
          cell.backgroundView =[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellBackground"]]autorelease]; 
          cell.selectedBackgroundView=[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SelectedCellBackground"]] autorelease]; 
         } 
    
         cell.textLabel.text = [[cellArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row -1]; //row -1 to compensate for the extra header row 
    
         return cell; 
        } 
    } 
    
  9. 現在實行willSelectRowAtIndexPath並返回零如果indexpath.row == 0,這將關心didSelectRowAtIndexPath方法永遠不會被段標題行解僱。

    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
        if (indexPath.row == 0) 
        { 
         return nil; 
        } 
    
        return indexPath; 
    } 
    
  10. 最後,在didSelectRowAtIndexPath方法,檢查(indexpath.row!= 0),並繼續進行。

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
        if (indexPath.row != 0) 
        { 
         int row = indexPath.row -1; //Now use 'row' in place of indexPath.row 
    
         //Do what ever you want the selection to perform 
        } 
    } 
    

有了這個,你就完成了。你現在有一個完美的滾動,非浮動部分標題。

0

檢查答案如何實現與標題故事板:Table Header Views in StoryBoards

還要注意的是,如果你不執行

viewForHeaderInSection:(NSInteger)section 

它不會浮動而這正是你想要什麼。

2

在思考如何解決這個問題時,我想起了關於UITableViewStyleGrouped的一個非常重要的細節。 UITableView實現分組樣式(單元格周圍的圓角邊框)的方式是將自定義backgroundView添加到UITableViewCells,而不是UITableView。每個單元格根據其在部分中的位置添加一個backgroundView(上部的行獲取部分邊界的上部,中間的部分獲取側邊界,底部獲得 - 下部)。因此,如果我們只是想要一個簡單的樣式,並且我們沒有爲我們的單元格定製backgroundView(這是90%的時間),那麼我們需要做的就是使用UITableViewStyleGrouped,並刪除自定義背景。這可以通過以下這兩個步驟來完成:

改變我們的tableView風格UITableViewStyleGrouped 添加以下行至cellForRow,就在我們返回的單元格:

cell.backgroundView = [[[UIView的頁頭] initWithFrame :cell.bounds] autorelease];

就是這樣。 tableView風格將變成完全像UITableViewStylePlain,除了浮動標題。

希望這會有所幫助!

0

要完全去除浮節頭節,你可以這樣做:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    return [[UIView alloc] init]; 
} 

return nil不起作用。

要禁用浮動但仍顯示節標題,您可以使用自己的行爲提供自定義視圖。

1

另一種方法是在你想要標題的那一個之前創建一個空白部分,並將標題放在該部分。由於該部分是空的,標題將立即滾動。

-2

我還有一個更簡單的解決方案,而不會自動佈局和一切通過XIB進行使用:

1 /放入tableview中的頭球攻門被拖動和直接在tableview中刪除它。

2在新制作的標題的Size Inspector中,只需更改自動調整大小:您應該只留下頂部,左側和右側錨點以及水平填充。

That's how it should be set for the header

這應該做的伎倆!從平原到

142

更改表格樣式分組(誰曾來到這裏,由於錯誤的表樣式)

let tableView = UITableView(frame: .zero, style: .grouped) 
5

最簡單的方式得到你想要設置你的表樣式, 分離風格是什麼UITableViewCellSeparatorStyleNone

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    return CGFLOAT_MIN; // return 0.01f; would work same 
} 

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 
    return [[UIView alloc] initWithFrame:CGRectZero]; 
} 

不要試圖返回頁腳視圖爲nil,不要忘記設置標題高度和標題視圖,之後你必須得到你想要的東西。

21

在你的Interface Builder中點擊您的問題表視圖

problem table view

然後導航到屬性檢查器和改變風格平原分組 ;)易

easy

1

您可以添加上面的一個Section(帶有零行),然後將上面的SectionFooterView設置爲當前節的headerView,footerView不會浮動。 希望它能提供幫助。

10

更改您的TableView風格:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped]; 

按照蘋果文檔的UITableView:

UITableViewStylePlain-一個普通的表視圖。任何節標題或 頁腳都顯示爲內聯分隔符,並在滾動表 視圖時顯示爲浮點。

UITableViewStyleGrouped-一個表格視圖,其各節顯示不同的 行組。部分頁眉和頁腳不會浮動。

希望這個小變化將幫助你..

5

還有一個取巧的辦法。主要想法是將節號加倍,第一個僅顯示headerView,而第二個顯示實際單元。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return sectionCount * 2; 
} 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    if (section%2 == 0) { 
     return 0; 
    } 
    return _rowCount; 
} 

什麼需要做的是落實headerInSection代表:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
    if (section%2 == 0) { 
     //return headerview; 
    } 
    return nil; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    if (section%2 == 0) { 
     //return headerheight; 
    } 
    return 0; 
} 

這種方法也有你的數據源的影響不大:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    int real_section = (int)indexPath.section/2; 
    //your code 
} 

與其他方法相比,這種方法是安全的,而不會改變tableview的frame或contentInsets。 希望這可能有所幫助。

-1

也許你可以簡單地做頭圖背景透明:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section { 
    view.tintColor = [UIColor clearColor]; 
} 

或者全局應用:

[UITableViewHeaderFooterView appearance].tintColor = [UIColor clearColor]; 
1

也許你可以上的tableView 使用scrollViewDidScroll並根據電流來改變contentInset可見標題。

它似乎適用於我的用例!

extension ViewController : UIScrollViewDelegate{ 

    func scrollViewDidScroll(_ scrollView: UIScrollView) { 
     guard let tableView = scrollView as? UITableView, 
      let visible = tableView.indexPathsForVisibleRows, 
      let first = visible.first else { 
      return 
     } 

     let headerHeight = tableView.rectForHeader(inSection: first.section).size.height 
     let offset = max(min(0, -tableView.contentOffset.y), -headerHeight) 
     self.tableView.contentInset = UIEdgeInsetsMake(offset, 0, -offset, 0) 
    } 
} 
1

對於斯威夫特3+

只需使用和頁腳的高度與以下設置爲零:

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { 
    return .leastNormalMagnitude 
} 
0

據@ samvermette的回答,我已經實現了上述Swift中的代碼使編碼器可以輕鬆使用swift。

let dummyViewHeight = CGFloat(40) 
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight)) 
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0) 
0

REF:https://stackoverflow.com/a/26306212

let tableView = UITableView(frame: .zero, style: .grouped)

PLUSE

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    if section == 0 { 
     return 40 
    }else{ 
     tableView.sectionHeaderHeight = 0 
    } 

    return 0 
} 

這有助於使用頭空間

相關問題