Ios 如何附加两个视图,以便将它们平移为一个视图

Ios 如何附加两个视图,以便将它们平移为一个视图,ios,objective-c,uikit-dynamics,uidynamicbehavior,Ios,Objective C,Uikit Dynamics,Uidynamicbehavior,我希望两个视图的行为就像它们是一个视图一样-这意味着如果视图1在“x”n像素上移动,我希望视图2在任意方向上在x轴上移动相同数量的像素-而不必计算所有类型的偏移等 我认为使用新的UIDynamicMator是一个很好的选择,所以我尝试了这个 UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(320-150, 150, 150, 100)]; v1.backgroundColor = [UIColor blackColor]; [self.

我希望两个视图的行为就像它们是一个视图一样-这意味着如果视图1在“x”n像素上移动,我希望视图2在任意方向上在x轴上移动相同数量的像素-而不必计算所有类型的偏移等

我认为使用新的UIDynamicMator是一个很好的选择,所以我尝试了这个

UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(320-150, 150, 150, 100)];
v1.backgroundColor = [UIColor blackColor];
[self.view addSubview:v1];

self.v1 = v1;
UIView *v2 = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width, 
                                                      0,
                                                      self.view.bounds.size.width,
                                                      self.view.bounds.size.height)];
v2.backgroundColor = [UIColor redColor];
[self.view addSubview:v2];
self.v2 = v2;

UIPanGestureRecognizer *p = 
 [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[v1 addGestureRecognizer:p];

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIAttachmentBehavior *att = 
 [[UIAttachmentBehavior alloc] initWithItem:self.v1 
                           offsetFromCenter:UIOffsetZero 
                             attachedToItem:self.v2 
                           offsetFromCenter:UIOffsetMake(0, 
                                         self.v1.center.y - self.v2.center.y)];
att.damping = 0;
[self.animator addBehavior:att];
self.att = att;

-(void)pan:(UIPanGestureRecognizer *)gesture {
    if(gesture.state == UIGestureRecognizerStateChanged) {
        CGPoint p = [gesture locationInView:self.view];
        // move only on x axis but keep on same y point
        self.v1.center = CGPointMake(p.x, self.v1.center.y);
        [self.animator updateItemUsingCurrentState:self.v1];

    }
}
但它们相互作用-小视图倾斜并改变其旋转和y位置


我希望-仅在一个轴上并且彼此硬连接-有任何方法可以做到这一点吗?

鉴于没有提供关于上下文的更多详细信息,我假设您希望两个视图之间的相对距离保持不变。如果真是这样,我不知道你为什么要考虑UIDynamicAnimator。相反,您可以将这两个视图嵌入到containerview中,然后操纵容器的原点,而不是单独操纵这两个视图。通过采用这种方法,您不必担心在移动另一个视图时重新计算一个视图的原点,反之亦然

self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
UIView *v2 = [[UIView alloc] initWithFrame:CGRectMake(100 0, 100, 100)];
[self.containerView addSubview:v1];
[self.containerView addSubview:v2];

// now, changing the origin of containerView will move v1 and v2 simultaniously
- (void)pan:(UIPanGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint p = [gesture locationInView:self.view];
        // move only on x axis but keep on same y point
        self.containerView.center = CGPointMake(p.x, self.containerView.center.y);
    }
}

作为替代方案,您可以使用autolayout并以满足需求的方式关联两个视图。然后,当移动其中一个视图时,另一个视图将相应地移动。但是,如果您实际使用UIDynamics来操纵该视图层次结构中的视图,则autolayout不是一种方法,因为autolayout和UIDynamics往往会相互干扰。

鉴于没有提供有关上下文的更多详细信息,我假设您希望两个视图之间的相对距离保持不变。如果真是这样,我不知道你为什么要考虑UIDynamicAnimator。相反,您可以将这两个视图嵌入到containerview中,然后操纵容器的原点,而不是单独操纵这两个视图。通过采用这种方法,您不必担心在移动另一个视图时重新计算一个视图的原点,反之亦然

self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
UIView *v2 = [[UIView alloc] initWithFrame:CGRectMake(100 0, 100, 100)];
[self.containerView addSubview:v1];
[self.containerView addSubview:v2];

// now, changing the origin of containerView will move v1 and v2 simultaniously
- (void)pan:(UIPanGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint p = [gesture locationInView:self.view];
        // move only on x axis but keep on same y point
        self.containerView.center = CGPointMake(p.x, self.containerView.center.y);
    }
}

作为替代方案,您可以使用autolayout并以满足需求的方式关联两个视图。然后,当移动其中一个视图时,另一个视图将相应地移动。但是,如果您实际使用UIDynamics操作该视图层次结构中的视图,则autolayout不是一种方法,因为autolayout和UIDynamics往往会相互干扰。

解决此问题的一个简单方法是将其中一个视图作为子视图添加到另一个视图中,或者将两者作为子视图添加到新视图中,仅用于对视图进行分组。但是,根据您打算如何使用视图,这可能不适用于您


如果要使一个视图成为另一个视图的子视图,但希望子视图在superview的边界之外可见,可以在superview上将CliptBounds设置为NO。

解决此问题的一个简单方法是将其中一个视图作为子视图添加到另一个视图中,或者将这两个视图作为子视图添加到新视图中,新视图仅用于对视图进行分组。但是,根据您打算如何使用视图,这可能不适用于您


如果要使一个视图成为另一个视图的子视图,但希望子视图在superview的边界之外可见,则可以在superview上将CliptBounds设置为NO。

在Pangestree中将v1原点“X”设置为v2原点“X”

-voidpan:UIPangEstureRecognitor*手势{

CGPoint point = [gesture locationInView:self.view];

CGRect boundsRect = CGRectMake(15, 40, 285, self.view.frame.size.height-60);

if (CGRectContainsPoint(boundsRect, point))
{
    v1.center = point;
}



v2.frame = CGRectMake(v1.frame.origin.x, v2.frame.origin.y, v2.frame.size.width, v2.frame.size.height);

}

在Pangestree中将v1原点“X”设置为v2原点“X”

-voidpan:UIPangEstureRecognitor*手势{

CGPoint point = [gesture locationInView:self.view];

CGRect boundsRect = CGRectMake(15, 40, 285, self.view.frame.size.height-60);

if (CGRectContainsPoint(boundsRect, point))
{
    v1.center = point;
}



v2.frame = CGRectMake(v1.frame.origin.x, v2.frame.origin.y, v2.frame.size.width, v2.frame.size.height);

}

别忘了将superview上的平移手势识别器和superview的alpha设置为0。我希望我可以将这两个视图添加到同一继承权中-但这是不可能的-一个视图属于表视图-另一个属于容器-因此它们之间实际上没有任何连接或相互了解-该示例仅用于演示目的因为我在玩弄它。目标是让两个视图一起移动-不可能自动布局-我现在正在做的是手动将“view2”的原点更改为“x”像素-但这是不稳定的,看起来不太好:在这种情况下,我认为没有简单的方法可以忽略手动更改原点。你可以考虑观察范围的起源何时发生变化。但是,如果它是UITableViewCell,由于单元重复使用,这可能会给您带来麻烦。别忘了将superview上的平移手势识别器和superview的alpha设置为0。我希望我可以将这两个视图添加到同一继承权中-但这是不可能的-一个视图属于表视图-另一个属于容器-因此它们之间确实没有连接或相互了解-这个例子只是为了演示,因为我在玩弄它。目标是让两个视图一起移动-不可能自动布局-我现在做的是手动将“view2”的原点更改为“x”像素-但这是不稳定的,看起来不太好:在这种情况下,我认为没有简单的方法可以忽略手动更改原点 . 你可以考虑观察范围的起源何时发生变化。然而,如果它是UITableViewCell,它可能会因为单元重用而给您带来麻烦。