【问题标题】:UIView drag (image and text)UIView 拖动(图像和文本)
【发布时间】:2011-02-13 03:35:09
【问题描述】:

当 UIView 有图像和文本时,是否可以在 iOS 屏幕上拖动它?例如小卡片。您能否指出类似(已解决)的主题?没找到。

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    根据 pepouze 的回答,这就是一个巧妙的解决方案(经过测试,有效!

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

    【讨论】:

    • 这段代码让 UIVIew 在你的手指下跳跃,干得好。
    【解决方案2】:

    虽然 UIView 没有内置支持随着用户拖动移动自身,但实现它应该不难。当您只处理视图上的拖动而不是其他操作(例如点击、双击、多点触控等)时,它会更容易。

    首先要做的是通过继承 UIView 来创建一个自定义视图,比如DraggableView。然后重写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: 和touchesEnd:withEvent) 也是如此。

    【讨论】:

      【解决方案3】:

      MHC's answer 的补充。

      如果你不想要视图的左上角 跳到你的手指下,你也可以覆盖touchesBegan 像这样:

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

      并将 MHC 的 touches 更改为:

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

      编辑:

      Arie Litovsky 提供了更优雅的解决方案,让您可以抛弃 ivar:https://stackoverflow.com/a/10378382/653513

      【讨论】:

        【解决方案4】:

        即使 rokjarc 解决方案有效,使用

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

        避免创建CGPoint offset 和调用touchesBegan:withEvent:

        【讨论】:

        • 不错的一个。但是您必须按照 diablosnuevos 的建议使用它 - 使用 CGRectOffset
        【解决方案5】:

        这是一个拖动a custom UIView的解决方案(可以通过它的transform进行缩放或旋转),它可以保存图像和/或文本(只需根据需要编辑Tile.xib):

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

        【讨论】:

          【解决方案6】:

          这对我有用。我的 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);
          

          }

          【讨论】:

            猜你喜欢
            • 2017-05-05
            • 2012-05-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-20
            • 2014-04-16
            • 1970-01-01
            相关资源
            最近更新 更多