Answers:
假设您有一个UIView带有背景图片的场景,并且有很多场景vehicles,您可以将每辆新车定义为UIButton(UIImageView也可能起作用):
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(imageTouch:withEvent:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
[self.view addSubview:button];
然后,您可以通过响应该UIControlEventTouchDragInside事件,将车辆移至所需位置,例如:
- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
    CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
    UIControl *control = sender;
    control.center = point;
}
与整体管理场景相比,单个车辆处理自己的阻力要容易得多。
除了ohho的答案外,我还尝试了类似的实现,但是没有“快速”拖动和居中拖动的问题。
按钮初始化为...
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
[button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
[self.view addSubview:button];
和方法实现:
- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
    UIControl *control = sender;
    UITouch *t = [[event allTouches] anyObject];
    CGPoint pPrev = [t previousLocationInView:control];
    CGPoint p = [t locationInView:control];
    CGPoint center = control.center;
    center.x += p.x - pPrev.x;
    center.y += p.y - pPrev.y;
    control.center = center;
}
我不是说,这是答案的完美解决方案。不过,我发现这是最简单的拖动解决方案。
我曾经想在多个其他uiview之间拖放uiview。在那种情况下,我找到了在包含所有放置区域和所有拖动山墙对象的超级视图中跟踪平移事件的最佳解决方案。不将事件侦听器添加到实际拖动视图的主要原因是,一旦更改了拖动视图的超级视图,我就会丢失正在进行的平移事件。
相反,我实现了一个相当通用的拖放解决方案,该解决方案可以在单个或多个拖放区域中使用。
我创建了一个简单的示例,可以在这里看到:在多个其他uiview之间拖放uiviews
如果您决定采用其他方法,请尝试使用uicontrol而不是uibutton。它们声明了addTarget方法,并且易于扩展-因此提供了自定义状态和行为。
-(void)funcAddGesture
{ 
 // DRAG BUTTON
        UIPanGestureRecognizer *panGestureRecognizer;
        panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragButton:)];
        panGestureRecognizer.cancelsTouchesInView = YES;
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(50, 100, 60, 60);
        [button addTarget:self action:@selector(buttontapEvent) forControlEvents:UIControlEventPrimaryActionTriggered];
        [button setImage:[UIImage imageNamed:@"button_normal.png"] forState:UIControlStateNormal];
        [button addGestureRecognizer:panGestureRecognizer];
        [self.view addSubview:button];
}
- (void)dragButton:(UIPanGestureRecognizer *)recognizer {
    UIButton *button = (UIButton *)recognizer.view;
    CGPoint translation = [recognizer translationInView:button];
    float xPosition = button.center.x;
    float yPosition = button.center.y;
    float buttonCenter = button.frame.size.height/2;
    if (xPosition < buttonCenter)
        xPosition = buttonCenter;
    else if (xPosition > self.view.frame.size.width - buttonCenter)
        xPosition = self.view.frame.size.width - buttonCenter;
    if (yPosition < buttonCenter)
        yPosition = buttonCenter;
    else if (yPosition > self.view.frame.size.height - buttonCenter)
        yPosition = self.view.frame.size.height - buttonCenter;
    button.center = CGPointMake(xPosition + translation.x, yPosition + translation.y);
    [recognizer setTranslation:CGPointZero inView:button];
}
- (void)buttontapEvent {
    NSLog(@"buttontapEvent");
}
              ohho的答案对我来说效果很好。如果您需要Swift 2.x版本:
override func viewDidLoad() {
    let myButton = UIButton(type: .Custom)
    myButton.setImage(UIImage(named: "vehicle"), forState: .Normal)
    // drag support
    myButton.addTarget(self, action:#selector(imageMoved(_:event:)), forControlEvents:.TouchDragInside)
    myButton.addTarget(self, action:#selector(imageMoved(_:event:)), forControlEvents:.TouchDragOutside)
}
private func imageMoved(sender: AnyObject, event: UIEvent) {
    guard let control = sender as? UIControl else { return }
    guard let touches = event.allTouches() else { return }
    guard let touch = touches.first else { return }
    let prev = touch.previousLocationInView(control)
    let p = touch.locationInView(control)
    var center = control.center
    center.x += p.x - prev.x
    center.y += p.y - prev.y
    control.center = center
}
              对于Swift 4简便的方法。😛
步骤1: 将您的按钮从情节提要连接到View Controller。并设置所有基本的自动布局约束
 @IBOutlet weak var cameraButton: UIButton!
步骤2: 在viewDidLoad()中为按钮添加Pan Gesture
self.cameraButton.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.panGestureHandler(panGesture:))))
第三步:
添加panGestureHandler
@objc func panGestureHandler(panGesture recognizer: UIPanGestureRecognizer) {
         let location = recognizer.location(in: view)
        cameraButton.center = location
    }
现在您的按钮动作
@IBAction func ButtonAction(_ sender: Any) {
        print("This is button Action")
    }
添加查看结果☝️