Buduję aplikację za pomocą ReactiveCocoa. Widok z góry to menu, które można przeciągnąć, a następnie przesunąć do góry. Muszę użyć dwóch różnych urządzeń do rozpoznawania gestów - jednego do ściągania i jednego do cofania. Tylko jeden może być włączony na raz - i jest mój problem. Stan.Jak używać ReactiveCocoa z Gesture Recognizers
Używam rozszerzenia BlocksKit do skonfigurowania narzędzia do rozpoznawania gestów.
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)];
}];
}
}];
W mojej metody initWithNibName:bundle:
, jestem konfigurowania następujące RACSubject
s.
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];
}
}];
Tu się dużo dzieje. Problem pogłębia fakt, że mam prawie podwojoną liczbę tematów, które tu wymieniłem (także dla rozpoznawania gestów panoramowania), oraz inny zestaw rozpoznań do podobnej interakcji ze stopką . To dużo tematów.
Moje pytanie składa się z dwóch części:
- Czy istnieje lepszy sposób, aby utworzyć rodzaj łączenia chcę? Ponownie używam niektórych tematów w moim geście push-up, który wygląda bardzo podobnie. Mam dużo
RACSubjects
i wydaje się być chytry. - Urządzenie służy zasadniczo do zarządzania stanem urządzeń do rozpoznawania gestów. Próbowałem powiązać ich właściwość
enabled
bez żadnego szczęścia. Masz tu jakieś rady?
Jeśli 'headerMovementSubject' był podawany z rozpoznawczego gestu ruchu (i odpowiadających sygnałów), jak by to działało? Czy nadal potrzebowałbym jawnej właściwości przedmiotu? –
Przedmioty są często zapachem kodu, ponieważ są zmiennymi w zasadzie zmiennymi. Zamiast tego skupiłbym się na łączeniu podmiotów rozpoznających gesty przesuwania i przesunięcia w górę (np. Za pomocą '+ CombineLatest:') w coś, co może być wykorzystane w powyższych transformacjach. –
Gotcha.Myślę, że widzę, jak to by działało. Dzięki! –