Iphone iOS中的基本拖放操作
我想有一个视图,其中有车辆行驶,用户也可以拖放。你认为这样做的最佳大规模战略是什么?最好是从代表车辆的视图中获取触摸事件,还是从更大的视图中获取触摸事件?有没有一个简单的拖放范例让你满意?不同策略的缺点是什么?我实际上会在车辆视图本身上跟踪拖动,而不是在大视图上跟踪拖动,除非有特别的理由不这样做 在一种情况下,我允许用户通过在屏幕上拖动项目来放置项目。 在这种情况下,我尝试了让俯视图和子视图都可以拖动。我发现,如果在UIView中添加几个“可拖动”视图,并处理如何拖动它们,代码会更简洁。我对父UIView使用了一个简单的回调来检查新位置是否合适——因此我可以用动画来指示Iphone iOS中的基本拖放操作,iphone,ipad,ios,drag-and-drop,touch,Iphone,Ipad,Ios,Drag And Drop,Touch,我想有一个视图,其中有车辆行驶,用户也可以拖放。你认为这样做的最佳大规模战略是什么?最好是从代表车辆的视图中获取触摸事件,还是从更大的视图中获取触摸事件?有没有一个简单的拖放范例让你满意?不同策略的缺点是什么?我实际上会在车辆视图本身上跟踪拖动,而不是在大视图上跟踪拖动,除非有特别的理由不这样做 在一种情况下,我允许用户通过在屏幕上拖动项目来放置项目。 在这种情况下,我尝试了让俯视图和子视图都可以拖动。我发现,如果在UIView中添加几个“可拖动”视图,并处理如何拖动它们,代码会更简洁。我对父U
我想拖动俯视轨迹也不错,但如果您想添加仍与用户交互的不可拖动视图(如按钮),则会稍微有点混乱。假设您有一个带有背景图像和许多
车辆的UIView
场景,您可以将每辆新车定义为ui按钮
(UIImageView可能也可以使用):
然后,您可以通过响应UIControlEventTouchDragInside
事件,将车辆移动到您想要的任何位置,例如:
- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
UIControl *control = sender;
control.center = point;
}
与整体管理场景相比,单个车辆处理自己的拖动要容易得多。我有一个案例,我想在多个其他UIView之间拖放UIView。在这种情况下,我找到了在超级视图中跟踪平移事件的最佳解决方案,该视图包含所有拖放区域和所有拖动对象。不将事件监听器添加到实际拖动视图的主要原因是,我在更改拖动视图的superview后立即丢失了正在进行的平移事件
相反,我实现了一个相当通用的拖放解决方案,可以用于单个或多个拖放区域
我创建了一个简单的示例,可以在这里看到:
如果您决定换一种方式,请尝试使用uicontrol而不是uibutton。它们声明addTarget方法,并且更易于扩展-因此提供自定义状态和行为。除了Oho的答案之外,我还尝试了类似的实现,但没有“快速”拖动和居中拖动的问题
按钮初始化为
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;
}
我不是说,这是一个完美的答案。尽管如此,我发现这是最简单的拖动解决方案。-(void)funcadd
-(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");
}
{
//拖动按钮
UIPanGestureRecognizer*panGestureRecognizer;
panGestureRecognizer=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(拖动按钮:)];
pangestrerecognizer.cancelsTouchesInView=YES;
UIButton*button=[UIButton button类型:UIButtonTypeCustom];
button.frame=CGRectMake(50,100,60,60);
[按钮添加目标:自操作:@selector(ButtontAppEvent)for ControlEvents:UIControlEventPrimaryActionTriggered];
[按钮设置图像:[UIImage ImageName:@“button_normal.png”]用于状态:UIControlStateNormal];
[按钮添加GestureRecognitor:PangestureRecognitor];
[self.view addSubview:按钮];
}
-(无效)拖动按钮:(UIPangestureRecognitor*)识别器{
UIButton*按钮=(UIButton*)识别器.view;
CGPoint translation=[识别器translationView:按钮];
float xPosition=button.center.x;
浮动y位置=按钮。中心。y;
浮动按钮中心=button.frame.size.height/2;
如果(X位置<按钮中心)
xPosition=按钮中心;
else if(xPosition>self.view.frame.size.width-buttonCenter)
xPosition=self.view.frame.size.width-buttonCenter;
如果(位置<按钮中心)
Y位置=按钮中心;
else if(位置>self.view.frame.size.height-按钮中心)
yPosition=self.view.frame.size.height-按钮中心;
button.center=CGPointMake(xPosition+translation.x,yPosition+translation.y);
[识别器setTranslation:CGPointZero查看:按钮];
}
-(无效)按钮排气口{
NSLog(“按钮事件”);
}
Oho的回答对我来说很有效。如果您需要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
}
以下是从iOS 11开始进行拖放的最佳方式:
为Swift 4提供了简便易行的方法。看起来很棒而且很简单!我将尝试一下。如果用户拖动按钮的速度快于动画更新的速度,此策略是否会导致拖动中断?如果他们的手指伸出盒子,它将停止接收图像移动:withEvent:调用,对吗?你怎么知道图像是否停止拖动?您如何知道手指已移出?ohho-是否可以偏移图像或按钮的拖动“手柄”,以便可以通过右上角或左上角拖动它?当我尝试获取异常时--[drag_move_textViewController imageTouch:withEvent:]:在示例代码中,无法识别的选择器发送到实例0x4B4B1C0,您在使用后定义UIControl*控件=发送方-不应该更早定义吗?@PeterJohnson:事实上,在这种情况下这并不重要。自从您提到的那一行之后,这个变量就没有更早的用法了:)那么CGPoint pPrev=[t previousLocationInView:control]呢;CGP点=[t位置视图:对照];前面这两行似乎都是指“控制”?哦,天哪!我怎么会错过呢-O。。。我已经编辑了答案。我添加了按钮表单界面生成器,我使用autolayout进行了一些登录。我确实隐藏了按钮,然后再次显示,当我这样做时,它会返回到原始位置。如何防止这种情况发生
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
}