Río*_*ire 5 architecture objective-c ios viper-architecture
根据VIPER设计模式,UIView动画代码应该放在哪里?
它应该在视图中还是在演示者中?
笔记:
我有一个CustomView,一旦触摸,我希望在屏幕上移动。
已CustomView添加到我的屏幕中ViewController
您应该将其放置在 [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\nRun 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}\nRun Code Online (Sandbox Code Playgroud)\n\n根据 VIPER,视图的职责是“向用户显示信息”和“检测用户交互\xe2\x80\x9d,并且不允许决定触摸后做什么,除非通知 [P]resenter关于此事件。演示者轮流决定做什么和调用
\n\n[self.viperView changeCustomViewState];\nRun 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\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n\n对于[P]resenter,我们需要在这种情况下定义协议:
\n\n@protocol VIPERPresenter\n- (void)userDidTouchViewWithPosition:(CGPoint)point;\n@end\nRun Code Online (Sandbox Code Playgroud)\n\n当用户触摸屏幕时,视图调用演示者来通知某些事件:
\n\n[self.viperPresenter userDidTouchViewWithPosition:point];\nRun 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];\nRun Code Online (Sandbox Code Playgroud)\n\n然后 [I]nteractor 要求 DataManager 使用 [E]ntity 中的算法以某种方式将这些坐标映射到新坐标(应该将其移动到右上角还是左上角),并用新坐标(角视图)通知 [P]resenter应该移动)。最后 Presenter 执行:
\n\n[self.viperView changeCustomViewRelatedPosition:newPosition];\nRun Code Online (Sandbox Code Playgroud)\n\n同样,动画代码作为布局的一部分放置在 [V]iew 内部。但决策(确切的参数)是由其他组件(Presenter、Interactor、Entity)定义的
\n| 归档时间: |
|
| 查看次数: |
727 次 |
| 最近记录: |