it-swarm-ru.tech

UIView drag (изображение и текст)

Можно ли перетащить UIView вокруг экрана iOS, когда на нем есть изображение и текст? например маленькие карточки. Не могли бы вы указать мне на подобную (решенную) тему? Я не нашел ни одного.

27
psimekjr

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

Первое, что нужно сделать, это создать собственное представление, скажем DraggableView, с помощью подкласса UIView. Затем переопределите метод UIView touchesMoved:withEvent:, и вы можете получить там текущее место перетаскивания и переместить DraggableView. Посмотрите на следующий пример.

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *aTouch = [touches anyObject];
    CGPoint location = [aTouch locationInView:self.superview];
    [UIView beginAnimations:@"Dragging A DraggableView" context:nil];
    self.frame = CGRectMake(location.x, location.y, 
                            self.frame.size.width, self.frame.size.height);
    [UIView commitAnimations];
}

И потому что все подпредставления объекта DraggableView тоже будут перемещены. Поэтому поместите все свои изображения и тексты как подвид объекта DraggableView.

То, что я реализовал здесь, очень просто. Однако, если вы хотите более сложное поведение для перетаскивания (например, пользователь должен нажать на представление в течение нескольких секунд, чтобы переместить представление), тогда вам придется переопределить другие методы обработки событий (touchesBegan: withEvent: и touchsEnd: withEvent) также.

33
MHC

Вот как должно выглядеть аккуратное решение, основанное на ответе Пепуза ( протестировано, работает! )

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *aTouch = [touches anyObject];
    CGPoint location = [aTouch locationInView:self];
    CGPoint previousLocation = [aTouch previousLocationInView:self];
    self.frame = CGRectOffset(self.frame, (location.x - previousLocation.x), (location.y - previousLocation.y));
}
36
Arie Litovsky

Дополнение к ответ MHC .

Если вы не хотите, чтобы верхний левый угол представления прыгал под вашим пальцем, вы также можете переопределить touchesBegan вот так:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *aTouch = [touches anyObject];

    offset = [aTouch locationInView: self];
}

и измените прикосновения MHC к:

 -(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 {
      UITouch *aTouch = [touches anyObject];
      CGPoint location = [aTouch locationInView:self.superview];

      [UIView beginAnimations:@"Dragging A DraggableView" context:nil];
      self.frame = CGRectMake(location.x-offset.x, location.y-offset.y, 
                              self.frame.size.width, self.frame.size.height);
      [UIView commitAnimations];
  }

вы также должны определить CGPoint offset в интерфейсе:

@interface DraggableView : UIView
{
    CGPoint offset;
}

Правка:

Арье Литовский предлагает более элегантное решение, позволяющее отказаться от ивара: https://stackoverflow.com/a/10378382/653513

24
Rok Jarc

Хотя решение rokjarc работает, используя 

CGPoint previousLocation = [aTouch previousLocationInView:self.superview];

избегает создания CGPoint offset и вызова touchesBegan:withEvent:

5
pepouze

Вот решение для перетаскивания пользовательского UIView (его можно масштабировать или поворачивать с помощью transform), которое может содержать изображения и/или текст (просто отредактируйте Tile.xib по мере необходимости):

app screenshot

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    CGPoint previous = [touch previousLocationInView:self];

    if (!CGAffineTransformIsIdentity(self.transform)) {
        location = CGPointApplyAffineTransform(location, self.transform);
        previous = CGPointApplyAffineTransform(previous, self.transform);
    }

    self.frame = CGRectOffset(self.frame,
                              (location.x - previous.x),
                              (location.y - previous.y));
}
2
Alexander Farber

Это работа для меня. Мой UIView вращается и масштабируется

- (void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
CGPoint previous = [touch previousLocationInView:self];

if (!CGAffineTransformIsIdentity(self.transform)) {
    location = CGPointApplyAffineTransform(location, self.transform);
    previous = CGPointApplyAffineTransform(previous, self.transform);
}
CGRect newFrame = CGRectOffset(self.frame,
                               (location.x - previous.x),
                               (location.y - previous.y));
float x = CGRectGetMidX(newFrame);
float y = CGRectGetMidY(newFrame);
self.center = CGPointMake(x, y);

}

0
Roman Bambura