web-dev-qa-db-ja.com

UITableViewセクションヘッダーのデフォルトのスクロール動作を変更する

2つのセクションを持つUITableViewがあります。シンプルなテーブルビューです。 viewForHeaderInSectionを使用して、これらのヘッダーのカスタムビューを作成しています。ここまでは順調ですね。

デフォルトのスクロール動作では、セクションが検出されると、次のセクションがスクロールして表示されるまで、セクションヘッダーがナビゲーションバーの下に固定されたままになります。

私の質問はこれです:セクションヘッダーが上部に固定されないようにデフォルトの動作を変更できますが、セクションバーの残りの部分でナビゲーションバーの下をスクロールしますか?

明らかな何かが欠けていますか?

ありがとう。

145
davidjhinson

この問題を解決する方法は、contentOffsetcontentInsetに従ってUITableViewControllerDelegateを調整することです(UIScrollViewDelegateを拡張):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
       CGFloat sectionHeaderHeight = 40;
   if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
       scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
   } else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
       scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
   }
}

ここでの唯一の問題は、トップに戻るときに少しバウンスが失われることです。


{注:「40」は、セクション0ヘッダーの正確な高さである必要があります。セクション0ヘッダーの高さよりも大きい数値を使用すると、指触りが影響を受けることがわかります( 「1000」で、バウンス動作が上部で少し奇妙に見えます。数値がセクション0のヘッダーの高さと一致する場合、指の感触は完全またはほぼ完全に見えます。}

173
awulf

また、上部にゼロ行のセクションを追加し、前のセクションのフッターを次のヘッダーとして使用することもできます。

86
voidStern

これを実行していた場合、プレーンスタイルのUITableViewにはスティッキヘッダーがあり、グループ化スタイルのヘッダーにはないという事実を利用します。少なくとも、カスタムテーブルセルを使用して、グループ化されたテーブルのプレーンセルの外観を模倣することを試みます。

私は実際にこれを試したことがありませんので、うまくいかないかもしれませんが、そうすることをお勧めします。

35
Colin Barrett

私はそれが遅れることを知っていますが、私は決定的な解決策を見つけました!

10個のセクションがある場合、dataSourceが20を返すようにします。セクションヘッダーには偶数を使用し、セクションコンテンツには奇数を使用します。このようなもの

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section%2 == 0) {
        return 0;
    }else {
        return 5;
    }
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        return [NSString stringWithFormat:@"%i", section+1];
    }else {
        return nil;
    }
}

ほら! :D

28
LocoMike

この問題をハッキングしない方法で解決するには、いくつかのことが必要です。

  1. テーブルビュースタイルをUITableViewStyleGroupedに設定します
  2. テーブルビューbackgroundColor[UIColor clearColor]に設定します
  3. backgroundColor [UIColor clearColor]を使用して、各テーブルビューセルのbackgroundViewを空のビューに設定します
  4. 必要に応じて、テーブルビューrowHeightを適切に設定するか、個々の行の高さが異なる場合はtableView:heightForRowAtIndexPath:をオーバーライドします。
15
Neil Gall

最初に投稿された ここ 、IBを使用した簡単なソリューション。同じことは非常に簡単ですが、プログラムで行うことができます。

これを達成するためのおそらく簡単な方法(IBを使用):

UIViewをTableViewにドラッグして、ヘッダービューにします。

  1. ヘッダービューの高さを100ピクセルに設定します
  2. Tableview contentInset(上)を-100に設定します
  3. セクションヘッダーは、通常のセルと同じようにスクロールします。

このソリューションは最初のヘッダーを隠すと言っている人もいますが、そのような問題に気付いていません。私にとっては完璧に機能し、これまで見てきた中で最もシンプルなソリューションでした。

15
Doc

ここまでで説明したソリューションに満足できなかったため、それらを組み合わせようとしました。結果は、@ awulfと@cescofryに触発された次のコードです。実際のテーブルビューヘッダーがないので、私にとってはうまくいきます。テーブルビューヘッダーが既にある場合は、高さを調整する必要があります。

// Set the Edge inset
self.tableView.contentInset = UIEdgeInsetsMake(-23.0f, 0, 0, 0);

// Add a transparent UIView with the height of the section header (ARC enabled)
[self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 23.0f)]];
14
Thomas Kekeisen

TableViewスタイルを変更するだけです:

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

ITableViewStyle Documentation

UITableViewStylePlain-プレーンテーブルビュー。セクションのヘッダーまたはフッターはインラインセパレーターとして表示され、テーブルビューがスクロールされるとフロートします。

UITableViewStyleGrouped-セクションが行の個別のグループを表示するテーブルビュー。セクションのヘッダーとフッターはフロートしません。

14
Arthur S

Select Grouped TableView style

ストーリーボードでtableViewの属性インスペクターからグループ化されたテーブルビュースタイルを選択します。

6
Arjun Shukla

TableViewスタイルを変更します。

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

UITableViewのAppleドキュメントに従って:

UITableViewStylePlain-プレーンテーブルビュー。セクションのヘッダーまたはフッターはインラインセパレーターとして表示され、テーブルビューがスクロールされるとフロートします。

UITableViewStyleGrouped-セクションが行の個別のグループを表示するテーブルビュー。セクションのヘッダーとフッターはフロートしません。この小さな変更があなたを助けることを願っています..

5
Aks

私は代替ソリューションを見つけました。実際のヘッダーセクションの代わりに各セクションの最初のセルを使用してください、このソリューションはそれほどきれいに見えませんが、うまく機能します。ヘッダーセクションに定義されたプロトタイプセルを使用して、メソッドで- cellForRowAtIndexPath indexPath.row == 0を要求します。trueの場合、ヘッダーセクションのプロトタイプセルを使用し、そうでない場合はデフォルトのプロトタイプセルを使用します。

4
AlexBB

テーブルのheaderViewを、セクションビューのヘッダーと同じ高さの透明なビューで設定します。また、-heightでyフレームを使用してテーブルビューを開始します。

self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, - height, 300, 400)];

UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)] autorelease];
[self.tableView setTableHeaderView:headerView];
4
cescofry

グループ化されたスタイルはiOS 7のプレーンスタイルと基本的に同じように見えるため(フラットネスと背景の点で)、私たちにとって最良かつ最も簡単な(つまり、最もハックの少ない)修正方法は、単にテーブルビューのスタイルをグループ化することです。 contentInsetsでのジャッキングは、スクロールアウェイナビゲーションバーを上部に統合するときは常に問題でした。グループ化されたテーブルビュースタイルでは、セルとまったく同じに見え、セクションヘッダーは固定されたままです。スクロールの奇妙さはありません。

2
Greg Combs

TableViewに負のインセットを割り当てます。 22pxの高セクションヘッダーがあり、reloadDataを追加した直後にスティッキーにしたくない場合:

self.tableView.contentInset = UIEdgeInsetsMake(-22, 0, 0, 0); 
self.tableView.contentSize = CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height+22); 

私にとって魅力的な作品です。セクションフッターにも機能します。代わりに、下部に負のインセットを割り当てるだけです。

1
Mike A

私の答えを確認してください こちら 。これは、ハッキングなしで非フローティングセクションヘッダーを実装する最も簡単な方法です。

0
Sumit Anantwar

テーブルをスクロールビューに追加すると、うまくいくようです。

0
Dolbex

素早いバージョンの@awulf回答。

func scrollViewDidScroll(scrollView: UIScrollView) {
    let sectionHeight: CGFloat = 80
    if scrollView.contentOffset.y <= sectionHeight {
        scrollView.contentInset = UIEdgeInsetsMake( -scrollView.contentOffset.y, 0, 0, 0)
    }else if scrollView.contentOffset.y >= sectionHeight {
        scrollView.contentInset = UIEdgeInsetsMake(-sectionHeight, 0, 0, 0)
    }
}
0
Jeff

@LocoMikeの答えは私のtableViewに最もよく適合しましたが、フッターを使用するときにも壊れました。したがって、これはヘッダーとフッターを使用する場合の修正されたソリューションです:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return (self.sections.count + 1) * 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section % 3 != 1) {
        return 0;
    }
    section = section / 3;
    ...
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section % 3 != 0) {
        return nil;
    }
    section = section / 3;
    ...
}

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

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if (section % 3 != 2) {
        return 0;
    }
    section = section / 3;
    ...
}

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

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    if (section % 3 != 2) {
        return nil;
    }
    section = section / 3;
    ...
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    int section = indexPath.section;
    section = section / 3;
    ...
}
0
marmor

TableViewスタイルを変更します。

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

UITableViewのAppleドキュメントに従って:

UITableViewStylePlain- A plain table view. Any section headers or footers are displayed as inline separators and float when the table view is scrolled.

UITableViewStyleGrouped- A table view whose sections present distinct groups of rows. The section headers and footers do not float.
Hope this small change will help you ..
0
Aks