【发布时间】:2011-02-13 03:35:09
【问题描述】:
当 UIView 有图像和文本时,是否可以在 iOS 屏幕上拖动它?例如小卡片。您能否指出类似(已解决)的主题?没找到。
【问题讨论】:
标签: iphone objective-c
当 UIView 有图像和文本时,是否可以在 iOS 屏幕上拖动它?例如小卡片。您能否指出类似(已解决)的主题?没找到。
【问题讨论】:
标签: iphone objective-c
根据 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 没有内置支持随着用户拖动移动自身,但实现它应该不难。当您只处理视图上的拖动而不是其他操作(例如点击、双击、多点触控等)时,它会更容易。
首先要做的是通过继承 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) 也是如此。
【讨论】:
对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
【讨论】:
即使 rokjarc 解决方案有效,使用
CGPoint previousLocation = [aTouch previousLocationInView:self.superview];
避免创建CGPoint offset 和调用touchesBegan:withEvent:
【讨论】:
CGRectOffset。
这是一个拖动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));
}
【讨论】:
这对我有用。我的 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);
}
【讨论】: