UIView перетаскивать (изображение и текст) - PullRequest
27 голосов
/ 13 февраля 2011

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

Ответы [ 6 ]

36 голосов
/ 30 апреля 2012

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

- (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));
}
33 голосов
/ 13 февраля 2011

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

Первое, что нужно сделать, это создать собственное представление, скажем, DraggableView, создав подкласс UIView. Затем переопределите метод touchesMoved:withEvent: в UIView, и вы можете получить текущее местоположение перетаскивания и переместить 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), а также.

24 голосов
/ 01 декабря 2011

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

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

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

    offset = [aTouch locationInView: self];
}

и изменить прикосновения MHCMoved на:

 -(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;
}

EDIT:

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

5 голосов
/ 30 апреля 2012

Даже при том, что решение rokjarc работает, использование

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

позволяет избежать создания CGPoint offset и вызова touchesBegan:withEvent:

2 голосов
/ 23 марта 2014

Вот решение для перетаскивания пользовательского 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));
}
0 голосов
/ 06 декабря 2015

Это работа для меня. Мой 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);

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...