2017-08-17 69 views
0

我在每個視圖中有兩個視圖和一個圖像。在第一個視圖中,我可以使用手勢縮放,旋轉和平移圖像。我想記錄每個這些轉換並將它們轉移到第二個視圖中的圖像,以便第二個圖像與第一個視圖中的第一個圖像顯示在完全相同的位置,但會有相反的縮放(如果第一個圖像圖像放大,然後第二個需要按相同的數量縮小)。如何將圖像的位置和比例轉移到其他視圖?

下面的代碼僅適用於圖像平移或旋轉但未縮放的情況。縮放完全改變圖像中心的位置,代碼不再正常工作。我該如何解決這個問題,使得第二張圖片的中心位置與第一張圖片的中心位置相同,無論縮放比例如何?

這裏的第一個視圖的視圖控制器:然後

import UIKit 

class FirstViewController: UIViewController { 

// MARK: Properties 
@IBOutlet weak var photo: UIImageView! 

// Variables for scaling 
var max_scale: CGFloat = 3.0 
var min_scale: CGFloat = 0.2 
var current_scale: CGFloat = 1.0 
var lastScale: CGFloat = 0.0 

// Position variables 
var translate_x: CGFloat = 0.0 
var translate_y: CGFloat = 0.0 
var scale: CGFloat = 1.0 
var angle: CGFloat = 0.0 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Do any additional setup after loading the view. 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

// MARK: Gesture actions 

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

@IBAction func panGesture(_ gestureRecognizer: UIPanGestureRecognizer) { 
    // Move the achor point of the view's layer to the touch point 
    // so that movig the view becomes simpler. 
    let piece = gestureRecognizer.view 
    self.adjustAnchorPoint(gestureRecognizer: gestureRecognizer) 

    // Apply the pan to the view's transform. 
    if gestureRecognizer.state == .began || gestureRecognizer.state == .changed { 
     //print((photo.frame.origin.x), (photo.frame.origin.y)) 
     // Get the distance moved since the last call to this method. 
     let translation = gestureRecognizer.translation(in: piece?.superview) 

     // Set the translation point to zero so that the translation distance 
     // is only the change since the last call to this method. 
     piece?.center = CGPoint(x: ((piece?.center.x)!+translation.x), y: ((piece?.center.y)!+translation.y)) 
     translate_x = (piece?.center.x)! 
     translate_y = (piece?.center.y)! 
     gestureRecognizer.setTranslation(CGPoint.zero, in: piece?.superview) 
    } 
} 

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

// MARK: - Navigation 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    let resultView = segue.destination as! SecondViewController 
    resultView.finalImage = photo.image! 

    resultView.translate_x_ = photo.frame.origin.x + UIScreen.main.bounds.width/2 
    resultView.translate_y_ = photo.frame.origin.y + UIScreen.main.bounds.height/2 
    resultView.scale_ = scale 
    resultView.angle_ = angle 
} 
} 

位置參數傳送到第二視圖控制器是這樣的:

override func viewDidLoad() { 
    super.viewDidLoad() 

    editedPhoto.image = finalImage 

    // Translate 
    editedPhoto.center = CGPoint(x: (UIScreen.main.bounds.width/2), y: (UIScreen.main.bounds.height/2)) 
    editedPhoto.center = CGPoint(x: (translate_x_), y: (translate_y_)) 

    // Scale 
    editedPhoto.transform = editedPhoto.transform.scaledBy(x: (1/scale_), y: (1/scale_)) 

    // Rotate 
    editedPhoto.transform = editedPhoto.transform.rotated(by: angle_) 
} 

回答

1

嗯...我試圖運行你的代碼 - 但我必須缺少設置步驟。如果我不對視圖進行任何更改(不拖動,捏或旋轉),則下一個查看器中的視圖不在位。

但是....

我想你遇到了麻煩,因爲你不佔改變.layer.anchorPoint

試試這個 -

SecondViewController,添加新的屬性(它將期間設置爲賽格瑞準備):

var anchorPoint_: CGPoint = CGPoint.zero 

然後,在viewDidLoad()

override func viewDidLoad() { 
    super.viewDidLoad() 

    editedPhoto.image = finalImage 

    // add this line 
    editedPhoto.layer.anchorPoint = anchorPoint_ 

    // Translate 
    editedPhoto.center = CGPoint(x: (translate_x_), y: (translate_y_)) 

    // Scale 
    editedPhoto.transform = editedPhoto.transform.scaledBy(x: (1/scale_), y: (1/scale_)) 

    // Rotate 
    editedPhoto.transform = editedPhoto.transform.rotated(by: angle_) 

} 

FirstViewController,爲準備賽格瑞變爲:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    let resultView = segue.destination as! SecondViewController 
    resultView.finalImage = photo.image! 

    resultView.anchorPoint_ = photo.layer.anchorPoint 

    resultView.translate_x_ = photo.center.x 
    resultView.translate_y_ = photo.center.y 

    resultView.scale_ = scale 
    resultView.angle_ = angle 
} 

認爲應該解決這個問題。

相關問題