首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >UIViews的伸缩组,但保持其位置

UIViews的伸缩组,但保持其位置
EN

Stack Overflow用户
提问于 2018-08-28 12:05:03
回答 3查看 111关注 0票数 1

我正在尝试使用收缩手势一次缩放多个UIViews (在基础视图上)。虽然它看起来很简单,但我正面临着让它正常工作的艰难时期。

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

代码语言:javascript
复制
----------------------------------------------
|                                            |
|    -------                      --------   |   
|    |     |                      |      |   |
|    |  V1 |   ---------------    |      |   |
|    |     | X |     v2      |  Y |   v3 |   |
|    -------   ---------------    |      |   |
|                                 --------   |
---------------------------------------------

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
   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。

有什么办法吗?任何帮助都是非常感谢的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-28 13:00:45

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

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

代码语言:javascript
复制
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中的扩展使得加减点成为可能。

票数 2
EN

Stack Overflow用户

发布于 2018-08-28 13:00:23

发生的情况是,您还相对于屏幕的角0,0缩放视图的x和y位置。你需要相对于屏幕的中心或者你的握手手势的中心来做。我不记得我的头顶,但我认为有一种方法来指定一个规模的锚点,如果没有,你将不得不手动计算位置调整。

票数 1
EN

Stack Overflow用户

发布于 2018-08-28 13:58:24

@EmilioPelaez Answer如预期的那样工作。这是他的伪代码的obj-c版本,如果有人感兴趣的话。

代码语言:javascript
复制
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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52049900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档