ReactiveCocoa を使用してアプリケーションを構築しています。トップビューは、プルダウンしてからプッシュアップできるメニューです。2 つの異なるジェスチャ認識機能を使用する必要があります。1 つは引き下げるため、もう 1 つは押し戻すためです。一度に有効にできるのは 1 つだけです。そこに私の問題があります。州。
BlocksKit 拡張機能を使用してジェスチャ認識エンジンをセットアップしています。
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)];
}];
}
}];
私のinitWithNibName:bundle:
方法では、次の s を設定しています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];
}
}];
ここでは多くのことが起こっています。この問題は、ここに挙げたサブジェクトの数のほぼ 2 倍 (パンアップ ジェスチャ レコグナイザーのサブジェクトも含む)と、フッターとの同様の相互作用のためのレコグナイザーの別のセットを持っているという事実によって悪化します。それは多くの科目です。
私の質問は2つの部分に分かれています:
- 私が望む種類の連鎖を設定するためのより良い方法はありますか? 腕立て伏せのジェスチャーでもいくつかの被写体を再利用していますが、これは非常によく似ています。私はたくさん持っていて、
RACSubjects
ジャンキーに見えます。 - は
menuFinishedTransitionSubject
基本的に、ジェスチャ レコグナイザの状態を管理するために使用されます。私は彼らの財産を束縛しようとしましたenabled
が、運がありませんでした。ここで何かアドバイスはありますか?