【问题标题】:Scale group of UIViews but keeping its position缩放 UIViews 组但保持其位置
【发布时间】:2018-08-28 04:05:02
【问题描述】:

我正在尝试使用捏合手势(在基本视图上)一次缩放多个 UIView。虽然它看起来很直,但我很难让它正常工作。

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

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

捏紧时,我通过使用缩放属性计算变换来缩放 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;

虽然这会均匀地缩放 3 个视图中的每一个,但我觉得中心点太偏离并且缩放看起来更奇怪。请检查以下问题的屏幕截图

如您所见,尽管比例按预期工作,并且所有 3 个视图一起缩放。中心仍然是一个问题。我希望从所有 3 个视图的实际位置进行缩放,我不希望它们在 gif 中像这样移动。

有办法吗?非常感谢任何帮助

【问题讨论】:

  • 不要改变视图中心的位置

标签: ios objective-c uiview transform scale


【解决方案1】:

如果我理解正确,您希望在缩放一组元素时采用通常的行为,即它们从所有选定元素的中心进行缩放。

我以前做过,它是在 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)
}

*CGMath 中的扩展使加减点成为可能。

【讨论】:

  • 感谢@EmilioPelaez,它很完美。奇迹般有效。 :) 在这里添加了我的 obj-c 版本的代码,以防有人感兴趣。
  • 我有一个类似的旋转分组视图的问题,如果你可以看看stackoverflow.com/questions/52052198/…
【解决方案2】:

发生的情况是,您还相对于屏幕角 0,0 缩放视图的 x 和 y 位置。您需要相对于屏幕中心或捏合手势的中心来执行此操作。我不记得了,但我认为有一种方法可以指定刻度的锚点,如果没有,您将不得不手动计算位置调整。

【讨论】:

    【解决方案3】:

    @EmilioPelaez 答案按预期工作。这是他的伪代码的 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多