【问题标题】:How to attach 2 views inorder for them to pan as one view如何附加 2 个视图以使它们作为一个视图平移
【发布时间】:2014-03-14 09:41:18
【问题描述】:

我希望 2 个视图表现得好像它们是“一个视图”——这意味着如果视图 1 在“x”n 个像素上移动,我希望视图 2 在 x 轴上移动相同数量的像素(在任意方向上) ) - 无需计算各种偏移量等。

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

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 位置。

我希望 - 仅在 1 个轴上并且“硬”相互连接 - 有什么方法可以做到这一点?

【问题讨论】:

    标签: ios objective-c uikit-dynamics uidynamicbehavior


    【解决方案1】:

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

    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);
        }
    }
    

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

    【讨论】:

    • 别忘了在superview和superview的alpha上设置平移手势识别器为0
    • 我希望我可以将两个视图添加到同一个层次结构中 - 但这是不可能的 - 一个视图属于表视图 - 另一个属于容器 - 所以他们真的没有联系或知识彼此 - 该示例仅用于演示目的(因为我正在玩它)。目标是让两个视图一起移动 - 自动布局是不可能的 - 我现在正在做的是手动将 'view2' 的原点更改为 'x' 像素 - 但这很不稳定而且看起来不太好:(跨度>
    • 在这种情况下,我认为没有一种简单的方法可以省略手动更改原点。您可以考虑KVO (simple explanation here) 以观察范围内视图的来源何时发生变化。但是,如果是UITableViewCell,可能会因为单元重复使用而给您带来麻烦。
    【解决方案2】:

    在 panGesture 中将 v1 原点 'X' 设置为 v2 原点 'X。

    -(void)pan:(UIPanGestureRecognizer *)手势{

    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);
    

    }

    【讨论】:

      【解决方案3】:

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

      如果您想让一个视图成为另一个视图的子视图,但希望子视图在父视图的边界之外可见,您可以在父视图上将 clipToBounds 设置为 NO

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-06
        相关资源
        最近更新 更多