缩放UIViews组,但保持其位置

时间:2018-08-28 04:05:03

标签: ios objective-c uiview transform scale

我试图用捏手势一次缩放多个UIView(在基本视图上)。尽管看起来很简单,但我仍然很难使其正常工作。

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

.toString(format)

在紧要关头,我正在通过使用比例属性计算转换来缩放3个视图中的每个视图

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

并使用当前比例更改每个视图的中心,像这样

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

尽管这会均匀缩放3个视图中的每个视图,但我感到中心点太偏了,并且缩放看起来很奇怪。请检查以下问题的屏幕截图

enter image description here

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

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

3 个答案:

答案 0 :(得分:2)

如果我的理解正确,那么在缩放一组元素时,您希望具有通常的行为,即使它们从所有选定元素的中心开始缩放。

我之前已经做过,它是在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中的扩展名使得添加和减去点成为可能。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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