ReactiveCocoaを使用してアプリケーションを構築しています。トップビューは、プルダウンしてからプッシュバックできるメニューです。私は2つの異なるジェスチャ認識器を使用しなければなりません - 一つは引き下げ、もう一つは押し戻すためです。一度に有効にできるのは1つだけです。問題があります。状態。ReactiveCocoaをジェスチャー認識ツールで使用する方法
私は、BlocksKit拡張機能を使用してジェスチャ認識機能を設定しています。私initWithNibName:bundle:
方法で
self.panHeaderDownGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) {
UIPanGestureRecognizer *recognizer = (UIPanGestureRecognizer *)sender;
CGPoint translation = [recognizer translationInView:self.view];
if (state == UIGestureRecognizerStateChanged)
{
[self.downwardHeaderPanSubject sendNext:@(translation.y)];
}
else if (state == UIGestureRecognizerStateEnded)
{
// Determine the direction the finger is moving and ensure if it was moving down, that it exceeds the minimum threshold for opening the menu.
BOOL movingDown = ([recognizer velocityInView:self.view].y > 0 && translation.y > kMoveDownThreshold);
// Animate the change
[UIView animateWithDuration:0.25f animations:^{
if (movingDown)
{
[self.downwardHeaderPanSubject sendNext:@(kMaximumHeaderTranslationThreshold)];
}
else
{
[self.downwardHeaderPanSubject sendNext:@(0)];
}
} completion:^(BOOL finished) {
[self.menuFinishedTransitionSubject sendNext:@(movingDown)];
}];
}
}];
、私は次のようRACSubject
秒を設定しています。
self.headerMovementSubject = [RACSubject subject];
[self.headerMovementSubject subscribeNext:^(id x) {
@strongify(self);
// This is the ratio of the movement. 0 is closed and 1 is open.
// Values less than zero are treated as zero.
// Values greater than one are valid and will be extrapolated beyond the fully open menu.
CGFloat ratio = [x floatValue];
CGRect headerFrame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), kHeaderHeight + ratio * kMaximumHeaderTranslationThreshold);
if (ratio < 0)
{
headerFrame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), kHeaderHeight);
}
self.headerViewController.view.frame = headerFrame;
}];
// This subject is responsible for receiving translations from a gesture recognizers and turning
// thos values into ratios. These ratios are fead into other signals.
self.downwardHeaderPanSubject = [RACSubject subject];
[self.downwardHeaderPanSubject subscribeNext:^(NSNumber *translation) {
@strongify(self);
CGFloat verticalTranslation = [translation floatValue];
CGFloat effectiveRatio = 0.0f;
if (verticalTranslation <= 0)
{
effectiveRatio = 0.0f;
}
else if (verticalTranslation <= kMaximumHeaderTranslationThreshold)
{
effectiveRatio = fabsf(verticalTranslation/kMaximumHeaderTranslationThreshold);
}
else
{
CGFloat overshoot = verticalTranslation - kMaximumHeaderTranslationThreshold;
CGFloat y = 2 * sqrtf(overshoot + 1) - 2;
effectiveRatio = 1.0f + (y/kMaximumHeaderTranslationThreshold);
}
[self.headerMovementSubject sendNext:@(effectiveRatio)];
}];
// This subject is responsible for mapping this value to other signals and state (ugh).
self.menuFinishedTransitionSubject = [RACReplaySubject subject];
[self.menuFinishedTransitionSubject subscribeNext:^(NSNumber *menuIsOpenNumber) {
@strongify(self);
BOOL menuIsOpen = menuIsOpenNumber.boolValue;
self.panHeaderDownGestureRecognizer.enabled = !menuIsOpen;
self.panHeaderUpGestureRecognizer.enabled = menuIsOpen;
self.otherViewController.view.userInteractionEnabled = !menuIsOpen;
if (menuIsOpen)
{
[self.headerViewController flashScrollBars];
}
}];
ここでは多くのことが起こっています。この問題は、私がここに挙げたように(パンアップジェスチャ認識装置のものも)、とのフッタと同様の相互作用のための別の認識器セットをほぼ倍増したという事実によって悪化する。それはたくさんのテーマです。私が欲しいの連鎖のようなものを設定するためのより良い方法はあり
- :
私の質問は二つの部分にありますか?私は、プッシュアップジェスチャーの中でいくつかのテーマを再利用しています。これは本当に似ています。私は
RACSubjects
をたくさん持っていて、それはジャッキーと思われます。 menuFinishedTransitionSubject
は、本質的にジェスチャ認識装置の状態を管理するために使用されます。私は彼らのenabled
プロパティを結束させようとしました。ここにアドバイスはありますか?
'headerMovementSubject'がムーブアップジェスチャ認識器(および対応する信号)から供給されていた場合、それはどのように機能しますか?私はまだ明示的なサブジェクトプロパティが必要でしょうか? –
主語は基本的に可変変数なので、コードの匂いがしばしばあります。代わりに、私はmove-downとmove-upジェスチャ認識子を(例えば '+ combineLatest:'を使って)上記の変換に繋がるものに組み合わせることに焦点を合わせます。 –
Gotcha。私はそれがどのように機能するかを見ていると思う。ありがとう! –