ここでの他の回答は、UINavigationBar の下にドロップダウンする通知の解決策を提供しているようです。UITableView のスクロールビューに収まるソリューションをまだ探している場合は、カスタム テーブル ヘッダー (セクション ヘッダーではない) をテーブル ビューに追加します。
これを達成するために必要な大まかな手順は次のとおりです。
1. ロード時に最初のヘッダー ビューを作成する
私は通常、(UITableViewController を使用する代わりに) UITableView インスタンス変数を所有する UIViewController サブクラスを使用しますが、どちらのセットアップでもこれを達成できるはずです。tableview セットアップ コード (おそらく viewDidLoad 内) で、backgroundColor、contentInset、separatorStyle などを設定する場所で、ヘッダーになる UILabel を作成します。次に、この UILabel を tableView の tableHeaderView に設定します。もちろん、この「通知セクション」をもう少し複雑なものにしたい場合は、入れ子になった UILabel + 何か他のものを持つ UIView にしてください。次のようなものです:
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 44.0f)];
headerLabel.backgroundColor = [UIColor clearColor]; // Just in case you have some fancy background/color in your table view
headerLabel.textAlignment = UITextAlignmentCenter;
headerLabel.font = ....
headerLabel.textColor = ....
headerLabel.text = @"You are an awesome user!";
self.tableView.tableHeaderView = headerLabel;
2.テーブルビューを「通常」にロードするように設定します(つまり、ヘッダーを表示しません)
繰り返しますが、viewDidLoad 内で、ロード時にこのヘッダー ビューを非表示にするには、tableview の contentOffset と alwaysBounceVertical を適切に設定する必要があります。ヘッダーの高さに設定された contentOffset は、テーブルビューの y 座標をヘッダーのすぐ下から開始します。alwaysBounceVertical を YES に設定すると、テーブルビューの contentsize が画面サイズよりも小さい場合でも、テーブルビューが正しく動作します。次のようなものです:
self.tableView.contentOffset = (CGPoint){0.0f, 44.0f};
self.tableView.alwaysBounceVertical = YES;
3.スライドを下に追加してスライドします
さて、これを行うにはいくつかの方法があります。viewDidAppear では、最初のアニメーションがテーブルビューを下にスライドする (つまり、contentOffset を {0.0f, 0.0f} に設定する) チェーン UIView アニメーションを作成できます。このアニメーションは 1 秒遅延し、2 番目のアニメーションはテーブルビューを元にスライドします (つまり、設定します)。 contentOffset to {0.0f, 44.0f}) は 2 秒遅れます。または、GCD を使用して、2 つのアニメーションを非同期 + 遅延ブロックとしてスケジュールすることもできます。どちらの方法でも問題ありません (これを実現するには、他におそらく 2 つまたは 3 つの良い方法があります) が、アイデアを理解するために...次のようにアニメーションを連鎖させることができます。
__weak MyCustomViewController *me = self;
[UIView
animateWithDuration:0.4f
delay:1.0f
options:UIViewAnimationOptionAllowUserInteraction
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f};
}
completion:^(BOOL finished)
{
if (me.tableView)
{
[UIView
animateWithDuration:0.4f
delay:2.0f
options:UIViewAnimationOptionAllowUserInteraction
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 44.0f};
}
completion:^(BOOL finished)
{
if (me.tableView)
{
me.tableView.tableHeaderView = nil; // If you want to completely get rid of this notification header
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f}; // I'm unsure if this will cause the tableview to jump... if it does, you can animate the headerview away instead of animating the tableview up to hide the header, then setting header to nil and reseting the contentOffset
// or
me.tableView.tableHeaderView.hidden = YES; // If you want to just hide the header
}
}];
}
}];
サンプルコードは何もテストせずに書いたのですが…ふふふ、多分そのままでは動きません。さらにヘルプが必要な場合は、喜んでお手伝いします。幸運を。
更新: ユーザーがスクロールしてアニメーションをキャンセルできるようにする
テーブルでのユーザー インタラクションがアニメーションに対して何をしたいのかよくわかりません。ユーザーがスクロールを開始したときにアニメーションをキャンセルしたい場合は、GCD を使用します (以下のコードを参照)。しかし、ユーザーのタッチでアニメーションを機能させる他の方法を見ることができるので、探しているものによって異なります。いずれにせよ、ユーザーのタッチが次のスケジュールされたアニメーションを無効にする必要があるとしましょう。次のような 2 つの機能を使用して実現できます。
- (void)scheduleShowHeaderAnimation
{
__weak MyCustomViewController *me = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0f * NSEC_PER_SEC), dispatch_get_main_queue(), ^ // Start animating after 1 sec delay
{
if (me.tableView) // Make sure the tableview is still around
{
if (! me.tableView.tracking && // Don't show animation if user has begun to touch contentview
! me.tableView.dragging && // Don't show animation if user has begun to drag contentview
! me.tableView.decelerating) // Don't show animation if dragging happened and scrollview is starting to decelerate
{
[UIView
animateWithDuration:0.4f
delay:0.0f
options:UIViewAnimationOptionAllowAnimatedContent // This will make sure user can interact with tableview while animation is going on
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f};
}
completion:^(BOOL finished)
{
[me scheduleHideHeaderAnimation];
}];
}
}
});
}
- (void)scheduleHideHeaderAnimation
{
__weak MyCustomViewController *me = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0f * NSEC_PER_SEC), dispatch_get_main_queue(), ^ // Start animating after 2 secs delay
{
if (me.tableView) // Make sure the tableview is still around
{
if (! me.tableView.tracking && // Don't show animation if user has begun to touch contentview
! me.tableView.dragging && // Don't show animation if user has begun to drag contentview
! me.tableView.decelerating) // Don't show animation if dragging happened and scrollview is starting to decelerate
{
[UIView
animateWithDuration:0.4f
delay:0.0f
options:UIViewAnimationOptionAllowAnimatedContent // This will make sure user can interact with tableview while animation is going on
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 44.0f};
}
completion:^(BOOL finished)
{
if (me.tableView)
{
me.tableView.tableHeaderView = nil; // If you want to completely get rid of this notification header
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f}; // I'm unsure if this will cause the tableview to jump... if it does, you can animate the headerview away instead of animating the tableview up to hide the header, then setting header to nil and reseting the contentOffset
// or
me.tableView.tableHeaderView.hidden = YES; // If you want to just hide the header
}
}];
}
}
});
}
viewDidAppear で scheduleShowHeaderAnimation を呼び出します。
次に、ユーザーが既にテーブルビューを下にスクロールしているときにヘッダーを非表示にすることをサポートするには、- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
または- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
UIScrollViewDelegate のいずれかを実装し、次のようなものを追加します。
if (self.tableView.tableHeaderView != nil)
{
self.tableView.tableHeaderView = nil;
}
// or
if (self.tableView.tableHeaderView.hidden == NO)
{
self.tableView.tableHeaderView.hidden = YES;
}
サポートしたいより複雑な操作がある場合、またはアニメーションをユーザーのタッチにさまざまな方法で応答させたい場合は、他の UIScrollViewDelegate メソッドをオーバーライドし、ユーザーがスクロールビュー (親クラスである) との操作を開始したときにオーバーライドする必要がある場合があります。テーブル ビューの)、アニメーションの動作を変更します。
これにより、探しているものに近づきますか?