UIView drag (image and text)

前端 未结 6 1883
悲&欢浪女
悲&欢浪女 2020-11-27 13:59

Is it possible to drag UIView around the iOS screen while it has both image and text? e.g. small cards. Could you point me to the similar (solved) topic? I haven\'t found an

相关标签:
6条回答
  • 2020-11-27 14:29

    Even though rokjarc solution works, using

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

    avoids the CGPoint offset creation and the call to touchesBegan:withEvent:

    0 讨论(0)
  • 2020-11-27 14:31

    This work for me. My UIView rotated and scaled

    - (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 讨论(0)
  • 2020-11-27 14:35

    While UIView does not have a built-in support for moving itself along the user dragging, it should be not so difficult to implement it. It is even easier when you are only dealing with dragging on the view, and not other actions such as tapping, double tapping, multi-touches etc.

    First thing to do is to make a custom view, say DraggableView, by subclassing UIView. Then override UIView's touchesMoved:withEvent: method, and you can get a current dragging location there, and move the DraggableView. Look at the following example.

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

    And because all subviews of the DraggableView object will be moved, too. So put all your images and texts as subviews of the DraggableView object.

    What I implemented here is very simple. However, if you want more complex behaviors for the dragging, (for example, the user have to tap on the view for a few seconds to move the view), then you will have to override other event handling methods (touchesBegan:withEvent: and touchesEnd:withEvent) as well.

    0 讨论(0)
  • 2020-11-27 14:35

    Here is a solution to drag a custom UIView (it can be scaled or rotated through its transform), which can hold images and/or text (just edit the Tile.xib as required):

    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 讨论(0)
  • 2020-11-27 14:41

    This is what a neat solution, based on pepouze's answer, would look like (tested, it works!)

    - (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));
    }
    
    0 讨论(0)
  • 2020-11-27 14:48

    An addition to MHC's answer.

    If you don't want the upper left corner of the view to jump under your finger, you can also override touchesBegan like this:

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

    and change MHC's touchesMoved to:

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

    you should also define CGPoint offset in the interface:

    @interface DraggableView : UIView
    {
        CGPoint offset;
    }
    

    EDIT:

    Arie Litovsky provides more elegant solution that allows you to ditch the ivar: https://stackoverflow.com/a/10378382/653513

    0 讨论(0)
提交回复
热议问题