我有一个非常简单的 UIImageView
,它包含在容器 View 中。它们大小相同,没有使用自动布局。当用户按下按钮时,UIImageView
应该旋转 90 度。当 UIImageView
(不是 UIImageView.image
)旋转时,它应该适合其父 View (.ScaleAspectFit
)。
到目前为止,我已经找到了最简单的部分:变换旋转。
self.currentRotation += 90
if self.currentRotation >= 360 {
self.currentRotation = 0
}
let angleInRadians: Double
switch self.currentRotation {
case 0:
angleInRadians = 0
case 90:
angleInRadians = M_PI_2
case 180:
angleInRadians = M_PI
case 270:
angleInRadians = M_PI + M_PI_2
default:
angleInRadians = 0
break;
}
let newTransform = CGAffineTransformRotate(CGAffineTransformIdentity, CGFloat(angleInRadians))
通过从 this question 获取一些信息,我能够编写 Swift 版本的辅助扩展,但我仍然不知道如何找到 UIImageView 的框架。
extension UIView {
var originalFrame: CGRect {
let currentTransform = self.transform
self.transform = CGAffineTransformIdentity
let originalFrame = self.frame
self.transform = currentTransform
return originalFrame
}
var transformedTopLeftPoint: CGPoint {
return self.transformedPointForOriginalPoint(originalFrame.topLeftPoint)
}
var transformedTopRightPoint: CGPoint {
return self.transformedPointForOriginalPoint(originalFrame.topRightPoint)
}
var transformedBottomLeftPoint: CGPoint {
return self.transformedPointForOriginalPoint(originalFrame.bottomLeftPoint)
}
var transformedBottomRightPoint: CGPoint {
return self.transformedPointForOriginalPoint(originalFrame.bottomRightPoint)
}
// helper to get point offset from center
func centerOffset(point: CGPoint) -> CGPoint {
return CGPoint(x: point.x - self.center.x, y: point.y - self.center.y)
}
// helper to get point back relative to center
func pointRelativeToCenter(point: CGPoint) -> CGPoint {
return CGPoint(x: point.x + self.center.x, y: point.y + self.center.y)
}
// helper to get point relative to transformed coords
func transformedPointForOriginalPoint(point: CGPoint) -> CGPoint {
// get offset from center
let offset = self.centerOffset(point)
// get transformed point
let transformedPoint = CGPointApplyAffineTransform(offset, self.transform)
// make relative to center
return self.pointRelativeToCenter(transformedPoint)
}
}
extension CGRect {
var topLeftPoint: CGPoint {
return self.origin
}
var topRightPoint: CGPoint {
return CGPoint(x: self.origin.x + self.size.width, y: self.origin.y)
}
var bottomLeftPoint: CGPoint {
return CGPoint(x: self.origin.x, y: self.origin.y + self.size.height)
}
var bottomRightPoint: CGPoint {
return CGPoint(x: self.origin.x + self.size.width, y: self.origin.y + self.size.height)
}
}
为了更好地说明,我附上了一张图片。
It shows a rotated view on top of its original frame (the smallest of the outlines) and the updated frame (the largest gray outline). The circles indicate the view's top-right corner before and after rotation. After the transform is applied, the frame updates to the minimum bounding box that encloses the view. Its new origin (the top-left corner of the gray outside box) has essentially nothing to do with the original view origin (the top-left corner of the black unrotated inner box). iOS does not provide a way to retrieve that adjusted point. Here are a series of view methods that perform that math for you. (UIView extension above)
我需要找到灰色框的框架。但即使使用这些方法,我仍然无法弄清楚该怎么做。实现我想要的结果的公式/算法是什么?
最佳答案
转换后 View 的 center
保持不变。所以你需要根据中心来计算东西。像这样:
func originalFrame() -> CGRect {
CGAffineTransform currentTransform = self.transform;
self.transform = CGAffineTransformIdentity;
let originalFrame = self.frame;
self.transform = currentTransform;
return originalFrame;
}
func centerOffset(point:CGPoint) -> CGPoint {
return CGPointMake(point.x - self.center.x, point.y - self.center.y);
}
func pointRelativeToCenter(point:CGPoint) -> CGPoint {
CGPointMake(point.x + self.center.x, point.y + self.center.y);
}
func newPointInView(point:CGPoint) -> CGPoint {
let offset = self.centerOffset(point)
let transformedPoint = CGPointApplyAffineTransform(offset, self.transform);
return self.pointRelativeToCenter(transformedPoint)
}
func newTopLeft() -> CGPoint {
let frame = self.originalFrame()
return self.newPointInView(frame)
}
func newTopRight() -> CGPoint {
let frame = self.originalFrame()
var point = frame.origin
point.x = point.x + frame.size.width
return self.newPointInView(point)
}
func newBottomLeft() -> CGPoint {
let frame = self.originalFrame()
var point = frame.origin
point.y = point.y + frame.size.height
return self.newPointInView(point)
}
func newBottomRight() -> CGPoint {
let frame = self.originalFrame()
var point = frame.origin
point.x = point.x + frame.size.width
point.y = point.y + frame.size.height
return self.newPointInView(point)
}
引用这个SO Thread了解更多详情。
关于ios - 变换旋转后如何找到UIView的框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33477247/