C4: добавить панорамирование к объекту, отличному от себя

Я посмотрел учебник C4 о добавлении жеста панорамирования к объекту и его анимации для возврата в исходное положение после завершения панорамирования. Я пытаюсь добавить это к трем отдельным объектам. Пока он работает с одним объектом, чтобы переместить его и сбросить в CGPoint, но чтобы он работал, я должен добавить жест панорамирования к «я», а не к объекту. Для справки, я в значительной степени использую код отсюда:

http://www.c4ios.com/tutorials/interactionPanning

Если я добавлю жест к самому объекту, конечно, он перемещается, но затем он просто остается в месте последнего касания. Однако я предполагаю, что оставление жеста на «я» повлияет не только на объект, который я хочу переместить, и я хочу иметь возможность перемещать три объекта по отдельности.


Я использую примерно ту же модификацию метода «перемещения», что и в примере:

-(void)move:(UIPanGestureRecognizer *)recognizer { 
    [character move:recognizer]; 
    if (recognizer.state == UIGestureRecognizerStateEnded) { 
        [character setCenter: charStartOrigin]; 
    } 
} 

А затем новый метод для создания объекта:

-(void)createCharacters { 
    character = [C4Shape ellipse:charStart]; 
    [character addGesture:PAN name:@"pan" action:@"move:"]; 
    [self.canvas addShape:character]; 
}

person Saelyria    schedule 07.10.2013    source источник
comment
Если вы можете опубликовать код, с которым вы работаете, я могу помочь более непосредственно.   -  person C4 - Travis    schedule 07.10.2013
comment
Я использую примерно ту же модификацию метода перемещения, что и в примере: -(void)move:(UIPanGestureRecognizer *)recognizer { [character move:recognizer]; if (recognizer.state == UIGestureRecognizerStateEnded) { [character setCenter: charStartOrigin]; } } А затем новый метод создания объекта: -(void)createCharacters { character = [C4Shape ellipse:charStart]; [символ addGesture:PAN name:@pan action:@move:]; [self.canvas addShape:character]; }   -  person Saelyria    schedule 08.10.2013


Ответы (1)


Пример ссылки, с которой вы работаете, скрыт. Поскольку я знал, что на холсте будет только один объект, я знал, что могу сделать так, будто я панорамирую этикетку. Это не будет работать для нескольких объектов, как вы уже поняли.

Чтобы разные объекты двигались независимо друг от друга и распознавали, когда они перетаскиваются, вам нужно создать подкласс для объектов и присвоить им собственные «способности».

Для этого я:

  1. Подкласс C4Shape
  2. Добавить пользовательское поведение в новый класс
  3. Создание подклассов объектов на холсте

Код для каждого шага выглядит следующим образом:

подклассы

Вы должны создать подкласс, который дает себе какое-то поведение. Поскольку вы работаете с фигурами, я тоже сделал это таким образом. Я называю свой подкласс Character, его файлы выглядят так:

Персонаж.h

#import "C4Shape.h"

@interface Character : C4Shape
@property (readwrite, atomic) CGPoint startOrigin;
@end

Я добавил к фигуре свойство, чтобы установить ее начальную точку (то есть точку, в которую она вернется).

Персонаж.m

#import "Character.h"

@implementation Character

-(void)setup {
    [self addGesture:PAN name:@"pan" action:@"move:"];
}

-(void)move:(UIGestureRecognizer *)sender {
    if(sender.state == UIGestureRecognizerStateEnded) {
        self.center = self.startOrigin;
    } else {
        [super move:sender];
    }
}

@end

В подклассе объекта C4 setup вызывается так же, как и для холста... Итак, здесь я добавляю жест для этого объекта. Установка запускается после вызова new или alloc/init.

Метод move: — это то место, где я хочу переопределить пользовательское поведение. В этом методе я перехватываю распознаватель жестов, и если его состояние равно UIGestureRecognizerStateEnded, я хочу выполнить анимацию обратно в исходное положение. В противном случае я хочу, чтобы он move: работал так, как должен, поэтому я просто вызываю [super move:sender], который запускает метод move: по умолчанию.

Вот и все для подкласса.

Создание подклассов объектов

Тогда мое рабочее пространство выглядит следующим образом:

#import "C4WorkSpace.h"
//1
#import "Character.h"

@implementation C4WorkSpace {
    //2
    Character *charA, *charB, *charC;
}

-(void)setup {
    //3
    CGRect frame = CGRectMake(0, 0, 100, 100);

    //4
    frame.origin = CGPointMake(self.canvas.width / 4 - 50, self.canvas.center.y - 50);
    charA = [self createCharacter:frame];
    frame.origin.x += self.canvas.width / 4.0f;
    charB = [self createCharacter:frame];
    frame.origin.x += self.canvas.width / 4.0f;
    charC = [self createCharacter:frame];

    //5
    [self.canvas addObjects:@[charA,charB,charC]];
}

-(Character *)createCharacter:(CGRect)frame {
    Character *c = [Character new];
    [c ellipse:frame];
    c.startOrigin = c.center;
    c.animationDuration = 0.25f;
    return c;
}

@end

Я добавил в свою рабочую область метод, который создает объект Character и добавляет его на экран. Этот метод создает объект Character, вызывая его метод new (мне приходится делать это так, потому что это подкласс C4Shape), превращает его в эллипс с рамкой, которую я ему дал, устанавливает его startOrigin, изменяет его animationDuration.

Вот что происходит с остальной частью рабочего пространства (ПРИМЕЧАНИЕ: шаги отмечены в приведенном выше коде):

  1. Я #import подкласс, чтобы я мог создавать объекты с ним
  2. Я создаю 3 ссылки на объекты Character.
  3. Я создаю каркас, который буду использовать для создания каждого из новых объектов.
  4. Для каждого объекта я перемещаю frame, изменяя его происхождение, а затем использую его для создания нового объекта с помощью написанного мной метода createCharacter:.
  5. Я добавляю все свои новые объекты в файл canvas.

ПРИМЕЧАНИЕ. Поскольку я создал свой подкласс со свойством startOrigin, я могу в этом классе всегда анимировать к этой точке. Я также могу установить эту точку с холста, когда захочу.

person C4 - Travis    schedule 07.10.2013
comment
P.S. заметили, как я добавил жест к self в подклассе? В данном случае он представляет объект Character, а не холст. Все подклассы в C4 (и ObjC) могут называть себя self. - person C4 - Travis; 08.10.2013
comment
Спасибо, это отлично работает! Однако просто для справки в будущем, поскольку я исхожу из фона Java - метод внизу, по сути, является «конструктором» для класса, да? Когда вы наследуете от C4Shape (C4Object) по сравнению с NSObject, нужно ли писать реализацию «конструктора» внутри WorkSpace, а не в файле .m? Еще раз спасибо! - person Saelyria; 08.10.2013
comment
В C4/ObjC конструкторы — это методы, начинающиеся со слова init. Базовый метод инициализации: -(id)init { ... }, поэтому метод, создающий персонажа, технически не является конструктором. Метод [Character new] просто оборачивает [[Character alloc] init];... По сути, это конструктор для класса Character. - person C4 - Travis; 08.10.2013