ReactiveCocoa를 사용하여 응용 프로그램을 작성하고 있습니다. 윗면보기는 아래로 끌어 내려서 되돌릴 수있는 메뉴입니다. 나는 두개의 다른 몸짓 인식기를 사용해야한다. 하나는 잡아 당기기위한 것이고 다른 하나는 뒤로 밀기위한 것이다. 한 번에 하나만 활성화 할 수 있으며 문제가 있습니다. 상태.제스처 인식 자와 함께 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
을 많이 가지고 있고 그것은 janky처럼 보인다. menuFinishedTransitionSubject
은 본질적으로 제스처 인식기의 상태를 관리하는 데 사용됩니다. 행운을 빌려서enabled
속성을 바인딩하려고했습니다. 여기에 어떤 조언이 있니?
'headerMovementSubject'가 제스처 인식기 (및 해당 신호)에서 제공되는 경우 어떻게 작동합니까? 나는 명백한 주제 재산이 여전히 필요합니까? –
피험자는 기본적으로 변경 가능한 변수이므로 코드 냄새가 자주 발생합니다. 대신, 위와 같은 변환에 사용할 수있는 무언가에'+ combineLatest :'를 사용하여 제스처 인식기 주제를 결합하는 데 중점을 둡니다. –
Gotcha.그게 어떻게 작동하는지 알 것 같습니다. 감사! –