特定の状況に対する ReactiveCocoa のアプローチに頭を悩ませようとしています。
セグメント コントローラーが子ビュー コントローラーを交換する状況があります。ここでいくつかのことを達成する必要があります。
- 親コントローラーに移動したら、iOS7 がカスタム コンテナー ビューでそれを処理しないため、
contentInset
のを更新する必要があります。tableView
- 検索が開始されたら、ナビゲーション バーをフェードさせ、
contentInset
アニメーションで更新する必要があります - 検索が終了したら、フェードインしてアニメーション
navigationBar
でリセットする必要がありますcontentInset
これを命令型スタイルで実現する現在のコードは次のとおりです。
- (void)didMoveToParentViewController:(UIViewController *)parent
{
[super didMoveToParentViewController:parent];
if (parent) {
CGFloat top = parent.topLayoutGuide.length;
CGFloat bottom = parent.bottomLayoutGuide.length;
if (self.tableView.contentInset.top != top) {
UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
self.tableView.contentInset = newInsets;
self.tableView.scrollIndicatorInsets = newInsets;
}
}
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
[UIView animateWithDuration:.25 animations:^{
self.navigationController.navigationBar.alpha=0;
self.tableView.contentInset = UIEdgeInsetsMake([UIApplication sharedApplication].statusBarFrame.size.height, 0, 0, 0);
}];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
[UIView animateWithDuration:.25 animations:^{
self.navigationController.navigationBar.alpha=1;
CGFloat top = self.parentViewController.topLayoutGuide.length;
CGFloat bottom = self.parentViewController.bottomLayoutGuide.length;
if (self.tableView.contentInset.top != top) {
UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
self.tableView.contentInset = newInsets;
self.tableView.scrollIndicatorInsets = newInsets;
}
}];
return YES;
}
挿入されたものの一部を引き出すようにリファクタリングできますが、この演習ではフラットに保ちます。
以下の回答として、「自分が何をしているのかほとんどわからない」アプローチを投稿します。
部分的な回答
わかりましたので、情報のストリームを関連するシグナルに引き出そうとしています。
基本的に私は知る必要があります:
- 私は現在探していますか?
- この場合の my
contentInset
(top)の現在の値
だから私のアプローチは
- 現在検索しているかどうかの RACSubject を作成します
self.currentlySearchingSignal
。 - myの
top
値をtableView.contentInset
シグナルに変換する sendNext:@(YES)
currentlySearchingSignal
いつ呼び出されるsearchBarShouldBeginEditing
か (そしていつ YES が返されるか)sendNext:@(NO)
currentlySearchingSignal
いつ呼び出されるsearchBarShouldEndEditing
か (そしていつ YES が返されるか)- ...
私は立ち往生しています。どういうわけかこれらを組み合わせる/サブスクライブする必要があることはわかっていますが、状態以外の方法で考えようとしています。
- 親 VC に追加され、
contentInset.top
まだ適切に設定されていない場合 (topLayoutGuide
)、アニメーションなしで設定する必要があります。 - 検索し、
contentInset.top
適切に設定されていない場合 (ステータス バー フレーム)、アニメーションを実行する必要があります (その後、アニメーションが完了するまでこれを更新しません)。 - 検索せず、
contentInset.top
適切に設定されていない場合 (topLayoutGuide
) アニメーションを実行する必要がある (アニメーションが完了するまで更新しない)
それを解決しようとしている
これが私のスタートです。#1を解決しようとしていますが、まだ機能していません。
- (void)viewDidLoad
{
[super viewDidLoad];
@weakify(self);
self.currentlyInSearchMode = [RACSubject subject];
self.contentInsetTop = RACObserve(self.tableView, contentInset);
RACSignal *parentViewControllerSignal = RACObserve(self, parentViewController);
// setup the insets when added to parent and not correctly set yet
[[[RACSignal combineLatest:@[self.contentInsetTop, parentViewControllerSignal]] filter:^BOOL(RACTuple *value) {
return !((NSValue *)value.first).UIEdgeInsetsValue.top == ((UIViewController *)value.second).topLayoutGuide.length;
}]doNext:^(id x) {
@strongify(self);
CGFloat top = self.parentViewController.topLayoutGuide.length;
CGFloat bottom = self.parentViewController.bottomLayoutGuide.length;
if (self.tableView.contentInset.top != top) {
UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
self.tableView.contentInset = newInsets;
self.tableView.scrollIndicatorInsets = newInsets;
}
}];
}