回答:
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を他の複数のUiviewの間にドラッグします
別の方法を選択する場合は、uibuttonの代わりにuicontrolを使用してみてください。これらはaddTargetメソッドを宣言し、拡張がはるかに簡単です-したがって、カスタムの状態と動作を提供します。
実際には、大きなビューではなく、車両ビュー自体のドラッグを追跡します-特に理由がない限り。
ユーザーがアイテムを画面上にドラッグして配置できるようにする場合。その場合、トップビューと子ビューの両方をドラッグできるようにしてみました。いくつかの「ドラッグ可能な」ビューをUIViewに追加し、それらをドラッグする方法を処理すると、コードがよりクリーンになることがわかりました。親UIViewへの単純なコールバックを使用して、新しい場所が適切かどうかを確認しました-アニメーションで示すことができました。
持つトップビューの私が推測するドラッグトラックは良いようですが、ボタンなど、まだ相互作用ユーザーと非ドラッグ可能なビューを、追加したい場合には、それより少し厄介になります。
-(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の答えは私にはうまくいきました。迅速な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
}
iOS 11でドラッグアンドドロップを行うには、次の方法が最適です。
Swift 4の場合簡単で簡単な方法。😛
ステップ1: ストーリーボードからView Controllerにボタンを接続します。すべての基本的なAutoLayout制約を設定します
@IBOutlet weak var cameraButton: UIButton!
手順2:viewDidLoad()で ボタンのパンジェスチャーを追加する
self.cameraButton.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.panGestureHandler(panGesture:))))
ステップ3:
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")
}
追加結果を見る☝️