ios – 如何将ReactiveCocoa与手势识别器一起使用

ios – 如何将ReactiveCocoa与手势识别器一起使用,第1张

概述我正在使用Reactive Cocoa构建应用程序.顶视图是一个菜单,可以向下拉,然后向上推.我必须使用两种不同的手势识别器 – 一种用于拉下,另一种用于推回.一次只能启用一个 – 这就是我的问题.州. 我正在使用BlocksKit扩展来设置手势识别器. self.panHeaderDownGestureRecognizer = [[UIPanGestureRecognizer alloc] in 我正在使用Reactive Cocoa构建应用程序.顶视图是一个菜单,可以向下拉,然后向上推.我必须使用两种不同的手势识别器 – 一种用于拉下,另一种用于推回.一次只能启用一个 – 这就是我的问题.州.

我正在使用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:方法中,我正在设置以下RACS主题.

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,CGRectGetWIDth(self.vIEw.bounds),kheaderHeight + ratio * kMaximumheaderTranslationThreshold);    if (ratio < 0)    {                    headerFrame = CGRectMake(0,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];    }}];

这里有很多事情要做.这个问题因为我已经在这里列出的主题数量几乎翻了一倍(用于泛起手势识别器的主题),再加上另一组用于与页脚进行类似交互的识别器而加剧了这个问题.这是很多科目.

我的问题分为两部分:

>有没有更好的方法来设置我想要的那种链?我在我的俯卧姿势中重新使用了一些主题,看起来非常相似.我有很多RACS主题,看起来很笨拙.
> menuFinishedTransitionSubject主要用于管理手势识别器的状态.我尝试绑定他们的启用属性没有任何运气.有什么建议吗?

解决方法 让我们关注显式订阅,因为这些通常是重写命令式代码的最佳结果.

首先,根据显示的代码,看起来headerMovementSubject只是从upwardheaderPanSubject(以及其他地方)输入的值.这是一个轻松的写作转换的候选人:

RACSignal *headerFrameSignal = [[self.downwardheaderPanSubject    map:^(NSNumber *translation) {        CGfloat verticalTranslation = [translation floatValue];        CGfloat effectiveRatio = 0.0f;        // Calculate effectiveRatio.        return @(effectiveRatio);    }]    map:^(NSNumber *effectiveRatio) {        // Calculate headerFrame.        return @(headerFrame);    }];

然后,我们可以使用绑定代替将self.headerVIEwController.vIEw.frame作为副作用进行 *** 作:

RAC(self.headerVIEwController.vIEw.frame) = headerFrameSignal;

我们可以在menuFinishedTransitionSubject中使用布尔值做类似的事情:

RAC(self.panheaderDownGestureRecognizer.enabled) = [self.menuFinishedTransitionSubject not];RAC(self.panheaderUpGestureRecognizer.enabled) = self.menuFinishedTransitionSubject;RAC(self.otherVIEwController.vIEw.userInteractionEnabled) = [self.menuFinishedTransitionSubject not];

不幸的是,-flashScrollbars仍然需要作为副作用调用,但我们至少可以解除块的过滤:

[[self.menuFinishedTransitionSubject    filter:^(NSNumber *menuIsOpen) {        return menuIsOpen.boolValue;    }]    subscribeNext:^(ID _) {        @strongify(self);        [self.headerVIEwController flashScrollbars];    }];

如果你想变得非常花哨,很多手势识别器逻辑可以用流转换来表示,动画可以用ReactiveCocoaLayout实现,但这是它自己的重写.

总结

以上是内存溢出为你收集整理的ios – 如何将ReactiveCocoa与手势识别器一起使用全部内容,希望文章能够帮你解决ios – 如何将ReactiveCocoa与手势识别器一起使用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1068970.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存