- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想拖动一个 UIView,并让它移动附加到它的其他 View 的位置,就好像它们都是通过字符串附加的一样。起始状态将是一堆 UIViews 聚集在一起。如果你拉出一个,一旦它与被拖动的 View 之间的最小距离达到最小距离,它所连接的项目就会开始移动。我当时认为实现此目的的最佳方法是使用 UIDynamicItemBehavior 考虑到我需要它回到原位并对其应用重量。我不太确定如何在不执行荒谬代码的情况下完成此操作。我的代码可以在下面看到。不幸的是,我遇到了正方形项目被拖回 square2 的问题。谁有任何建议,我很乐意澄清是否需要。
- (void)viewDidLoad
{
[super viewDidLoad];
_containmentView = [[UIView alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height/2, self.view.frame.size.width, 200)];
[self.view addSubview:_containmentView];
[_containmentView setBackgroundColor:[UIColor greenColor]];
_square = [[UIView alloc]initWithFrame:CGRectMake(200, 0, 100, 100)];
_square.backgroundColor = [UIColor yellowColor];
[_containmentView addSubview:_square];
_square2 = [[UIView alloc]initWithFrame:CGRectMake(100, 0, 100, 100)];
_square2.backgroundColor = [UIColor redColor];
[_containmentView addSubview:_square2];
_animator = [[UIDynamicAnimator alloc]initWithReferenceView:_containmentView];
_gravity = [[UIGravityBehavior alloc]initWithItems:@[_square, _square2]];
_gravity.gravityDirection = CGVectorMake(-1.0, 0.0);
[_animator addBehavior:_gravity];
_collision = [[UICollisionBehavior alloc]initWithItems:@[_square]];
_collision.collisionDelegate = self;
_collision.translatesReferenceBoundsIntoBoundary = YES; //causes the boundary to use the bounds of the reference view supplied to the UIDynamicAnimator
[_animator addBehavior:_collision];
UIDynamicItemBehavior *itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:@[_square]];
itemBehaviour.elasticity = 0.6;
[_animator addBehavior:itemBehaviour];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[_square addGestureRecognizer:gesture];
UIAttachmentBehavior *attach = [[UIAttachmentBehavior alloc] initWithItem:_square2 attachedToItem:_square];
[_animator addBehavior:attach];
}
-(void)handlePan:(UIPanGestureRecognizer *)gesture
{
CGPoint touchPoint = [gesture locationInView:self.view];
UIView* draggedView = gesture.view;
if (gesture.state == UIGestureRecognizerStateBegan) {
// 1. was the pan initiated from the upper part of the recipe?
UIView* draggedView = gesture.view;
CGPoint dragStartLocation = [gesture locationInView:draggedView];
_draggingView = YES;
_previousTouchPoint = touchPoint;
// [_animator updateItemUsingCurrentState:draggedView];
} else if (gesture.state == UIGestureRecognizerStateChanged && _draggingView) {
// 2. handle dragging
float xOffset = _previousTouchPoint.x - touchPoint.x;
gesture.view.center = CGPointMake(draggedView.center.x - xOffset,
draggedView.center.y);
_previousTouchPoint = touchPoint;
// [_animator updateItemUsingCurrentState:draggedView];
} else if (gesture.state == UIGestureRecognizerStateEnded && _draggingView) {
// 3. the gesture has ended
// [self tryDockView:draggedView];
// [self addVelocityToView:draggedView fromGesture:gesture];
[_animator updateItemUsingCurrentState:draggedView];
_draggingView = NO;
}
}
最佳答案
您需要使用附件来拖动您的形状,以便动画师可以使用其物理引擎计算每个项目的位置。
这是你的 viewDidLoad 更新:
- (void)viewDidLoad
{
[super viewDidLoad];
_containmentView = [[UIView alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height/2, self.view.frame.size.width, 200)];
[self.view addSubview:_containmentView];
[_containmentView setBackgroundColor:[UIColor greenColor]];
_square = [[UIView alloc]initWithFrame:CGRectMake(200, 0, 100, 100)];
_square.backgroundColor = [UIColor yellowColor];
[_containmentView addSubview:_square];
_square2 = [[UIView alloc]initWithFrame:CGRectMake(100, 0, 100, 100)];
_square2.backgroundColor = [UIColor redColor];
[_containmentView addSubview:_square2];
_animator = [[UIDynamicAnimator alloc]initWithReferenceView:_containmentView];
_gravity = [[UIGravityBehavior alloc]initWithItems:@[_square, _square2]];
_gravity.gravityDirection = CGVectorMake(-1.0, 0.0);
[_animator addBehavior:_gravity];
_collision = [[UICollisionBehavior alloc]initWithItems:@[_square, _square2]];
_collision.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_collision];
UIDynamicItemBehavior *itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:@[_square, _square2]];
itemBehaviour.elasticity = 0.6;
[_animator addBehavior:itemBehaviour];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[_square addGestureRecognizer:gesture];
UIPanGestureRecognizer *gesture2 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[_square2 addGestureRecognizer:gesture2];
UIAttachmentBehavior *attach = [[UIAttachmentBehavior alloc] initWithItem:_square2 attachedToItem:_square];
attach.damping = 1.6;
attach.frequency = 10;
[_animator addBehavior:attach];
}
我为两种形状都添加了重力、平移和碰撞。
这里应该看看你的 handlePan 方法:
-(void)handlePan:(UIPanGestureRecognizer *)gesture
{
CGPoint touchPoint = [gesture locationInView:_containmentView];
UIView* draggedView = gesture.view;
if (gesture.state == UIGestureRecognizerStateBegan) {
// 1. was the pan initiated from the upper part of the recipe?
_draggingView = YES;
_previousTouchPoint = touchPoint;
// Add a new attachment on the selected view;
self.attachment = [[UIAttachmentBehavior alloc] initWithItem:draggedView attachedToAnchor:touchPoint];
[self.animator addBehavior:self.attachment];
// Could temporarily remove gravity here
} else if (gesture.state == UIGestureRecognizerStateChanged && _draggingView) {
// 2. handle dragging
[self.attachment setAnchorPoint:touchPoint];
} else if (gesture.state == UIGestureRecognizerStateEnded && _draggingView) {
// 3. the gesture has ended
_draggingView = NO;
[self.animator removeBehavior:self.attachment];
// If gravity was removed, add it back here
}
}
您可能希望在拖动时暂时移除重力。看看我的评论,看看你可以在哪里做(并且不要忘记在拖动结束时把它放回去)。
如您所见,您确实需要更少的代码来以这种方式处理手势 :)。
您可以同时调整附件的阻尼、频率和长度,使形状对拖动手势做出不同的 react 。您还可以使用 UIDynamicItemBehavior 的 density
属性为形状添加密度。
关于ios - 使用 UIAttachmentBehavior 拖动 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20620866/
documentation UIAttachmentView 中的 length 属性如下: Use this property to adjust the attachment length, if
我已经向我的 tableviewcell 添加了一个水平的 UIPanGestureRecognizer 来平移单元格的 subview ,就像 ios7 邮件应用程序显示删除和更多选项的方式一样,这
我在使用 initWithItem:attachedToItem: 时遇到问题 初始化连接一个动态项的中心点到另一个动态项的中心点的附件行为。但是当我使用方法 pan 改变 topview 的中心点时
在使用 Xcode 5.1.1 在 iOS7 中使用新的物理引擎时,我编写了以下代码: #import "ZViewController.h" @interface ZViewController (
我在 IB 中设置了一个 UIScrollView,它具有包含 UIImageView 的自动布局。您可以查看 Evgenii 的 Github 存储库以了解其设置方式:https://github.
我想拖动一个 UIView,并让它移动附加到它的其他 View 的位置,就好像它们都是通过字符串附加的一样。起始状态将是一堆 UIViews 聚集在一起。如果你拉出一个,一旦它与被拖动的 View 之
我想使用 UIKit Dynamics 组合 UIAttachmentBehavior 和 UICollisionBehavior,以便用户可以拖动 View (使用 UIPanGestureReco
我有一个水平的 UICollectionView 和一个自定义的 UICollectionViewFlowLayout ,它在每个单元格上设置了一个 UIAttachmentBehavior 以在向左
在 UIButton 的子类中,我将 UIButton 附加到 UIAttachmentBehavior,它允许用户用手指在屏幕上拖动按钮。 在 - (void)touchesBegan:(NSSet
我刚从 Apple 开发者门户网站下载 DynamicsCatalog.xcodeproj,但出现此错误: “UIAttachmentBejavior”没有可见的@interface decleare
我是一名优秀的程序员,十分优秀!