代码之家  ›  专栏  ›  技术社区  ›  RameshVel

缩放UIViews组但保持其位置

  •  1
  • RameshVel  · 技术社区  · 7 年前

    假设我有三个这样堆叠的视图

    ----------------------------------------------
    |                                            |
    |    -------                      --------   |   
    |    |     |                      |      |   |
    |    |  V1 |   ---------------    |      |   |
    |    |     | X |     v2      |  Y |   v3 |   |
    |    -------   ---------------    |      |   |
    |                                 --------   |
    ---------------------------------------------
    

    在pinch上,我通过使用scale属性计算转换来缩放3个视图中的每一个

    CGAffineTransform v1Transform =  CGAffineTransformScale( v1.transform,recognizer.scale, recognizer.scale);
    v1.transform = v1Transform
    CGAffineTransform v2Transform =  CGAffineTransformScale( v2.transform,recognizer.scale, recognizer.scale);
    v2.transform = v2Transform
    CGAffineTransform v3Transform =  CGAffineTransformScale( v3.transform,recognizer.scale, recognizer.scale);
    v3.transform = v3Transform
    

    并使用当前比例更改每个视图的中心,如下所示

       CGPoint v1Center = CGPointMake(v1.center.x * recognizer.scale,  node.imgView.center.y * recognizer.scale);
       CGPoint v2Center = CGPointMake(v2.center.x * recognizer.scale,  node.imgView.center.y * recognizer.scale);
       CGPoint v3Center = CGPointMake(v3.center.x * recognizer.scale,  node.imgView.center.y * recognizer.scale);
      v1.cente = v1Center;
      v2.center = v2Center;
      v3.center = v3Center;
    

    虽然这三个视图的比例是一致的,但我觉得中心点太偏了,比例看起来更奇怪。请检查以下问题的屏幕截图

    enter image description here

    有办法吗?非常感谢您的帮助

    3 回复  |  直到 7 年前
        1
  •  2
  •   EmilioPelaez    7 年前

    如果我理解正确,您需要在缩放一组元素时的常规行为,这是为了让它们从所有选定元素的中心进行缩放。

    我以前做过,它在Swift中,它使用了我创建的一个名为 CGMath *,但它应该足够好作为伪代码:

    let scale = recognizer.scale
    //  Reset the scale of the recognizer. We'll scale the views by the change in the last tick.
    recognizer.scale = 1
    //  Get the center of all selected views as a CGPoint
    let center = views.map { $0.center }.reduce(CGPoint.zero, +) / CGFloat(views.count)
    views.forEach {
        //  Scale the view
        $0.scale *= scale
        //  Get the distance from this view to the center of all views, this is a CGPoint
        let distance = $0.center - center
        //  Multiply the distance by the scale and add it to the center of all views. Set that as the view's center.
        $0.center = center + (distance * scale)
    }
    

        2
  •  1
  •   drekka    7 年前

    发生的事情是,你也在缩放视图的x和y位置,相对于0,0,屏幕的一角。你需要根据屏幕的中心或者你捏的姿势的中心来做。我记不起来了,但我认为有一种方法可以指定刻度的定位点,如果没有,你就必须手动计算位置调整。

        3
  •  0
  •   RameshVel    7 年前

    @埃米利奥佩雷斯的回答工作正常。这是他的伪代码的obj-c版本

    CGPoint newCenter =CGPointZero;
    for(UIView *node in self.selectedNodes){
        newCenter = CGPointMake(newCenter.x + node.center.x, newCenter.y + node.center.y);
    }
    
    newCenter = CGPointMake(newCenter.x/self.selectedNodes.count, newCenter.y/self.selectedNodes.count);
    for(UIview *node in self.selectedNodes){
        CGAffineTransform newTransform =  CGAffineTransformScale( node.transform,recognizer.scale, recognizer.scale);
        node.transform = newTransform;
        CGPoint distance = CGPointMake(node.center.x - newCenter.x, node.center.y - newCenter.y);
        CGPoint delta= CGPointMake(distance.x * recognizer.scale, distance.y * recognizer.scale);
        node.center =CGPointMake(newCenter.x + delta.x, newCenter.y + delta.y);
    }