VIPER中UIView动画代码放置在哪里?

Río*_*ire 5 architecture objective-c ios viper-architecture

根据VIPER设计模式,UIView动画代码应该放在哪里?

它应该在视图中还是在演示者中?

笔记:

我有一个CustomView,一旦触摸,我希望在屏幕上移动。

CustomView添加到我的屏幕中ViewController

cur*_*ous 3

您应该将其放置在 [R]outer 中。这篇文章对此进行了很好的描述:

\n\n
\n

由于演示器包含对用户输入做出反应的逻辑,因此演示器知道何时导航到另一个屏幕以及导航到哪个屏幕。同时,线框知道如何导航。\n 因此,演示者将使用线框来执行导航。\n 它们一起描述从一个屏幕到下一个屏幕的路线。

\n\n

线框也是处理导航过渡动画的明显位置。

\n
\n\n

请注意,他们将路由器称为线框。

\n\n

更新(根据问题和评论的更新回答更正)

\n\n

我\xe2\x80\x99将根据这些 文章给出我的意见。\n让我们考虑两种情况:简单和更复杂。在简单的情况下,任务只是将视图的位置更改为带有动画的预定义位置(即更改状态)。在更复杂的情况下,任务是根据触摸坐标更改自定义视图的位置。

\n\n

看一下简单的案例。您有一个包含自定义视图的 [V]iewController。ViewController采用ViperView协议:

\n\n
@protocol VIPERView\n- (void)changeCustomViewState;\n@end\n\n@interface ViewController : UIViewController<VIPERView>\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

在实现中我们有这样的事情:

\n\n
@implementation ViewController {\n    BOOL _isInitialState;\n    IBOutlet UIView *_customView;\n}\n\n- (void)changeCustomViewState\n{\n    _isInitialState = !_isInitialState;\n    [self changeCustomViewPositionAnimated:YES];\n}\n\n- (void)changeCustomViewPositionAnimated:(BOOL)animated\n{\n    void(^performChange)() = ^() {\n        if (_isInitialState)\n            _customView.center = CGPointMake(50, 50);\n        else\n            _customView.center = CGPointMake(250, 250);\n    };\n\n    if (animated)\n    {\n        [UIView animateWithDuration:[CATransaction animationDuration] animations:^{\n            performChange();\n        }];\n    }\n    else\n    {\n        performChange();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据 VIPER,视图的职责是“向用户显示信息”和“检测用户交互\xe2\x80\x9d,并且不允许决定触摸后做什么,除非通知 [P]resenter关于此事件。演示者轮流决定做什么和调用

\n\n
[self.viperView  changeCustomViewState];\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,执行位于 [V]iew 中但 [P]resenter 中的动画的实际代码会触发其执行(因为它的职责是“告诉视图要显示什么”和“处理事件”)。\n定义自定义视图的位置只是查看\xe2\x80\x99s布局。所以它\xe2\x80\x99是配置的一部分。主持人只是将其以动画方式播放。

\n\n

在更复杂的情况下,我们\xe2\x80\x99将考虑根据触摸位置更改自定义视图\xe2\x80\x99的位置。\n我们的任务是在触摸后更改视图的位置,使其保留在屏幕上。例如,如果视图位于屏幕的左下角,则触摸不应将其移动到屏幕边界下方或屏幕左侧后面。它应该将视图移动到三个自由角之一。\n在这种情况下,我们的视图协议将如下所示:

\n\n
@protocol VIPERView\n// @param - related position to the screen bounds in range (0;1)\n- (void)changeCustomViewRelatedPosition:(CGPoint)point animated:(BOOL)animated;\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

并在实施中

\n\n
@implementation ViewController {\n    IBOutlet UIView *_customView;\n}\n\n- (void)changeCustomViewRelatedPosition:(CGPoint)point animated:(BOOL)animated\n{\n     CGPoint thisCoordinateSpacePoint = // translate \xe2\x80\x98point\xe2\x80\x99 to screen\xe2\x80\x99s coordinate space ;\n    void(^performChange)() = ^() {\n        _customView.center = thisCoordinateSpacePoint;\n    };\n\n    if (animated)\n    {\n        [UIView animateWithDuration:[CATransaction animationDuration] animations:^{\n            performChange();\n        }];\n    }\n    else\n    {\n        performChange();\n    }\n}\n\n- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event\n{\n    CGPoint point = //determine location\n    [self.viperPresenter userDidTouchViewWithPosition:point];\n}\n\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于[P]resenter,我们需要在这种情况下定义协议:

\n\n
@protocol VIPERPresenter\n- (void)userDidTouchViewWithPosition:(CGPoint)point;\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

当用户触摸屏幕时,视图调用演示者来通知某些事件:

\n\n
[self.viperPresenter userDidTouchViewWithPosition:point];\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如文章所述:

\n\n
\n

视图向演示者通知事件,其部分工作是相应地处理这些事件。这通常意味着要求交互器检索一些信息或执行一些任务。

\n
\n\n

在我们的例子中,应用程序需要确定视图应移动到的坐标。该算法可以被封装并且可以互换。所以我们可以从不同的地方检索这个算法:数据库、服务器等。为了完成这个任务,我们使用 [I]Interactor:

\n\n
 // in Presenter class\n[self.viperInteractor handleCoordinates:(CGPoint)point];\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后 [I]nteractor 要求 DataManager 使用 [E]ntity 中的算法以某种方式将这些坐标映射到新坐标(应该将其移动到右上角还是左上角),并用新坐标(角视图)通知 [P]resenter应该移动)。最后 Presenter 执行:

\n\n
[self.viperView changeCustomViewRelatedPosition:newPosition];\n
Run Code Online (Sandbox Code Playgroud)\n\n

同样,动画代码作为布局的一部分放置在 [V]iew 内部。但决策(确切的参数)是由其他组件(Presenter、Interactor、Entity)定义的

\n