我有這是爲了響應捏圖像,旋轉和平移手勢的視圖。我想要捏和圖像的旋轉將相對於放置在屏幕的中間定位點來完成,正是因爲它使用Xcode的iPhone模擬器按選項鍵完成。我怎樣才能把在屏幕中間的錨點如果圖像的中心可能被縮放和平移,以不同的位置?廣場錨點,而這樣做的手勢
這裏是我的縮放和旋轉手勢功能:
@IBAction func pinchGesture(_ gestureRecognizer: UIPinchGestureRecognizer) {
// Move the achor point of the view's layer to the touch point
// so that scaling the view and the layer becames simpler.
self.adjustAnchorPoint(gestureRecognizer: gestureRecognizer)
// Scale the view by the current scale factor.
if(gestureRecognizer.state == .began) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = gestureRecognizer.scale
}
if (gestureRecognizer.state == .began || gestureRecognizer.state == .changed) {
let currentScale = gestureRecognizer.view!.layer.value(forKeyPath:"transform.scale")! as! CGFloat
// Constants to adjust the max/min values of zoom
let kMaxScale:CGFloat = 15.0
let kMinScale:CGFloat = 1.0
var newScale = 1 - (lastScale - gestureRecognizer.scale)
newScale = min(newScale, kMaxScale/currentScale)
newScale = max(newScale, kMinScale/currentScale)
let transform = (gestureRecognizer.view?.transform)!.scaledBy(x: newScale, y: newScale);
gestureRecognizer.view?.transform = transform
lastScale = gestureRecognizer.scale // Store the previous scale factor for the next pinch gesture call
scale = currentScale // Save current scale for later use
}
}
@IBAction func rotationGesture(_ gestureRecognizer: UIRotationGestureRecognizer) {
// Move the achor point of the view's layer to the center of the
// user's two fingers. This creates a more natural looking rotation.
self.adjustAnchorPoint(gestureRecognizer: gestureRecognizer)
// Apply the rotation to the view's transform.
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
gestureRecognizer.view?.transform = (gestureRecognizer.view?.transform.rotated(by: gestureRecognizer.rotation))!
// Set the rotation to 0 to avoid compouding the
// rotation in the view's transform.
angle += gestureRecognizer.rotation // Save rotation angle for later use
gestureRecognizer.rotation = 0.0
}
}
func adjustAnchorPoint(gestureRecognizer : UIGestureRecognizer) {
if gestureRecognizer.state == .began {
let view = gestureRecognizer.view
let locationInView = gestureRecognizer.location(in: view)
let locationInSuperview = gestureRecognizer.location(in: view?.superview)
// Move the anchor point to the the touch point and change the position of the view
view?.layer.anchorPoint = CGPoint(x: (locationInView.x/(view?.bounds.size.width)!), y: (locationInView.y/(view?.bounds.size.height)!))
view?.center = locationInSuperview
}
}
編輯
我看到人們並不急於進入這個。分享一下我在過去幾天所取得的進展,讓我來幫助。
首先,我寫了一個函數centerAnchorPoint
其圖像的錨點正確地放置到屏幕的中心,無論是定位點以前在哪裏。然而,圖像不能縮放或旋轉才能起作用。
func setAnchorPoint(_ anchorPoint: CGPoint, forView view: UIView) {
var newPoint = CGPoint(x: view.bounds.size.width * anchorPoint.x, y: view.bounds.size.height * anchorPoint.y)
var oldPoint = CGPoint(x: view.bounds.size.width * view.layer.anchorPoint.x, y: view.bounds.size.height * view.layer.anchorPoint.y)
newPoint = newPoint.applying(view.transform)
oldPoint = oldPoint.applying(view.transform)
var position = view.layer.position
position.x -= oldPoint.x
position.x += newPoint.x
position.y -= oldPoint.y
position.y += newPoint.y
view.layer.position = position
view.layer.anchorPoint = anchorPoint
}
func centerAnchorPoint(gestureRecognizer : UIGestureRecognizer) {
if gestureRecognizer.state == .ended {
view?.layer.anchorPoint = CGPoint(x: (photo.bounds.midX/(view?.bounds.size.width)!), y: (photo.bounds.midY/(view?.bounds.size.height)!))
}
}
func centerAnchorPoint() {
// Position of the current anchor point
let currentPosition = photo.layer.anchorPoint
self.setAnchorPoint(CGPoint(x: 0.5, y: 0.5), forView: photo)
// Center of the image
let imageCenter = CGPoint(x: photo.center.x, y: photo.center.y)
self.setAnchorPoint(currentPosition, forView: photo)
// Center of the screen
let screenCenter = CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY)
// Distance between the centers
let distanceX = screenCenter.x - imageCenter.x
let distanceY = screenCenter.y - imageCenter.y
// Find new anchor point
let newAnchorPoint = CGPoint(x: (imageCenter.x+2*distanceX)/(UIScreen.main.bounds.size.width), y: (imageCenter.y+2*distanceY)/(UIScreen.main.bounds.size.height))
//photo.layer.anchorPoint = newAnchorPoint
self.setAnchorPoint(newAnchorPoint, forView: photo)
let dotPath = UIBezierPath(ovalIn: CGRect(x: photo.layer.position.x-2.5, y: photo.layer.position.y-2.5, width: 5, height: 5))
layer.path = dotPath.cgPath
}
功能setAchorPoint
在這裏用來錨點設置到一個新的位置不移動的圖像。
然後,我通過它的結束將這個更新的功能panGesture
:
if gestureRecognizer.state == .ended {
self.centerAnchorPoint()
}
EDIT 2
好了,我會盡量簡單地解釋一下上面的代碼。
什麼我做的是:
- 尋找照片的中心和屏幕
- 的中心之間的距離套用這個公式找到定位點的新位置:
newAnchorPointX =(imageCenter.x-distanceX)/ screenWidth + distanceX/screenWidth
然後對y位置做同樣的操作。
- 設置此點作爲新的錨點,而無需使用
setAnchorPoint
功能
正如我所說的這個工作很大如果圖像不進行縮放移動的照片。如果是,那麼錨點不會停留在中心。
奇怪的是distanceX或distanceY並不完全依賴於刻度值,所以這樣的事情不是做得比較工作:
newAnchorPointX =(imageCenter.x-distanceX)/屏幕寬度+ distanceX /(scaleValue *屏幕寬度)
EDIT 3
我想出縮放。看來,正確的比例因子是:
scaleFactor = photo.frame.size.width/photo.layer.bounds.size.width
我用這個來代替scaleValue
,它出色地工作。
所以完成平移和縮放。剩下的唯一東西就是旋轉,但它似乎是最難的。
我想的第一件事是到旋轉矩陣適用於X增量和Y方向上,類似這樣的:
let incrementX = (distanceX)/(screenWidth)
let incrementY = (distanceY)/(screenHeight)
// Applying rotation matrix
let incX = incrementX*cos(angle)+incrementY*sin(angle)
let incY = -incrementX*sin(angle)+incrementY*cos(angle)
// Find new anchor point
let newAnchorPoint = CGPoint(x: 0.5+incX, y: 0.5+incY)
然而,這是行不通的。
如果圖像放大,然後嘗試乘以distanceX * zoomScale和distanceY相同 –
我已更新問題。現在縮放工作正常。唯一剩下的就是旋轉。 – Kaspis245