Вы должны поместить его в [R] внешнее. Это хорошо описано в this article:
Поскольку Presenter содержит логику, чтобы реагировать на входы пользователей, это презентатор, который знает, когда для перехода на другой экран, и который экрана, чтобы перейти к. Между тем, каркас знает, как перемещаться. Итак, презентатор будет использовать каркас для выполнения навигации. Вместе они описывают маршрут с одного экрана на другой.
Каркас также является очевидным местом для обработки перехода на посадку анимации.
Обратите внимание, что они называются Router как Wireframe.
Update (исправления ответа на основе обновлений вопроса и комментарии)
Я выскажу свое мнение, основанное на thesearticles. Давайте рассмотрим два случая: простые и более сложные. В простом случае задача состоит в том, чтобы просто изменить позицию представления на предопределенный с помощью анимации (т. Е. Изменить состояние). И в более сложном случае задачей является изменение позиции пользовательского представления на основе координат касания.
Взгляните на простой корпус. У вас есть [V] iewController, который содержит пользовательский вид. ViewController принимает протокол ViperView:
@protocol VIPERView
- (void)changeCustomViewState;
@end
@interface ViewController : UIViewController<VIPERView>
@end
В реализации у нас есть что-то вроде этого:
@implementation ViewController {
BOOL _isInitialState;
IBOutlet UIView *_customView;
}
- (void)changeCustomViewState
{
_isInitialState = !_isInitialState;
[self changeCustomViewPositionAnimated:YES];
}
- (void)changeCustomViewPositionAnimated:(BOOL)animated
{
void(^performChange)() = ^() {
if (_isInitialState)
_customView.center = CGPointMake(50, 50);
else
_customView.center = CGPointMake(250, 250);
};
if (animated)
{
[UIView animateWithDuration:[CATransaction animationDuration] animations:^{
performChange();
}];
}
else
{
performChange();
}
}
В обязанности зрения в соответствии с VIPER является «отображение информации для пользователя» и «обнаружить взаимодействие с пользователем», и это ISN «т позволить принимать решения о том, что делать после того, как контакт, за исключением уведомления [P] resenter об этом событии. Presenter в свою очередь, принимает решение, что делать, и называет
[self.viperView changeCustomViewState];
Таким образом, фактический код, который выполняет анимацию, расположенную в [V] iew, но [P] resenter, запускает ее выполнение (поскольку его обязанности «сообщают, что отображать» и «Управлять событиями»). Определение позиции пользовательского представления - это часть макета представления. Так что это часть конфигурации. Презентатор просто превращает его в анимированный способ.
В более сложном случае мы рассмотрим изменение позиции пользовательского вида в зависимости от местоположения касания. Наша задача - изменить положение вида после касания таким образом, чтобы оно оставалось на экране. Например, если вид расположен в нижнем левом углу экрана, прикосновение не должно перемещать его ниже границ экрана или позади левой стороны экрана. Он должен перемещать вид в одном из трех свободных углов. В этом случае наш протокол для представления будет выглядеть примерно так:
@protocol VIPERView
// @param - related position to the screen bounds in range (0;1)
- (void)changeCustomViewRelatedPosition:(CGPoint)point animated:(BOOL)animated;
@end
и в реализации
@implementation ViewController {
IBOutlet UIView *_customView;
}
- (void)changeCustomViewRelatedPosition:(CGPoint)point animated:(BOOL)animated
{
CGPoint thisCoordinateSpacePoint = // translate ‘point’ to screen’s coordinate space ;
void(^performChange)() = ^() {
_customView.center = thisCoordinateSpacePoint;
};
if (animated)
{
[UIView animateWithDuration:[CATransaction animationDuration] animations:^{
performChange();
}];
}
else
{
performChange();
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CGPoint point = //determine location
[self.viperPresenter userDidTouchViewWithPosition:point];
}
@end
Для [P] resenter нам необходимо определить протокол, в этом случае:
@protocol VIPERPresenter
- (void)userDidTouchViewWithPosition:(CGPoint)point;
@end
Когда пользователь прикасается к экрану, зритель звонит ведущему, чтобы уведомить об этом событии:
[self.viperPresenter userDidTouchViewWithPosition:point];
В статье говорится:
Ведущий уведомляется о событиях по мнению и часть его работы является для обработки этих событий соответственно. Обычно это означает, что с помощью интерактивного устройства можно получить некоторую информацию или выполнить какую-либо задачу.
В нашем случае приложение должно определять координаты, в которых следует перемещать представление. Этот алгоритм может быть инкапсулирован и взаимозаменяем. Таким образом, мы могли бы получить этот алгоритм из разных мест: базы данных, сервер и т.д. Для выполнения этой задачи мы используем [I] nteractor:
// in Presenter class
[self.viperInteractor handleCoordinates:(CGPoint)point];
Тогда [I] nteractor просит DataManager, чтобы отобразить эти координаты на новые как-то с помощью алгоритм из [E] ntity (должен ли он перемещаться в верхнем правом или верхнем левом углу) и уведомляет обратно [P] resenter с новыми координатами (угол обзора должен перемещаться). И, наконец, Ведущий выполняет:
[self.viperView changeCustomViewRelatedPosition:newPosition];
Снова, код анимации размещен внутри [V] iew как часть макета. Но решение (точные параметры) определяются другими компонентами (Presenter, Interactor, Entity)
теги, которые вы использовали не являются для этого вопроса. Пожалуйста, просмотрите [Что такое теги и как их использовать?] (// stackoverflow.com/help/tagging) – SmokeDispenser