检索缩放的UIView

时间:2017-05-15 22:13:43

标签: ios swift uiview position scale

在缩放视图时,我无法在iPhone屏幕中检索视图的当前位置。 这是我所做的最简单的例子。

我在屏幕上有一个椭圆视图。当我点击时,它会增长并开始颤抖以显示它已被选中。然后我可以在屏幕上拖动视图。

以下是代码:

的ViewController

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // The View
    let toDrag = MyView(frame: CGRect(x: 0, y: 0, width: 50, height: 40))
    toDrag.center = CGPoint(x:100, y:100)
    // The gesture recognizer
    let panGestRec = UIPanGestureRecognizer(target: self, action:#selector(self.panView(sender:)))
    toDrag.addGestureRecognizer(panGestRec)

    self.view.addSubview(toDrag)
}

func panView(sender: UIPanGestureRecognizer) {
    guard let senderView = sender.view else { return }

    if sender.state == .recognized { print("Pan Recognized", terminator:"")}
    if sender.state == .began { print("Pan began", terminator: "") }
    if sender.state == .changed { print("Pan changed", terminator: "") }
    if sender.state == .ended { print("Pan ended", terminator: "") }

    let point = senderView.convert(senderView.center, to: nil)

    print (" point \(point)")
    let translation = sender.translation(in: self.view)
    senderView.center = CGPoint(x: senderView.center.x + translation.x, y: senderView.center.y + translation.y)
    sender.setTranslation(CGPoint.zero, in: self.view)
}
}

MyView的

import UIKit

class MyView: UIView {

var isAnimated: Bool = false

override init(frame: CGRect) {
    super.init(frame: frame) // calls designated initializer
    self.isOpaque = false
    self.backgroundColor = UIColor.clear
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.isOpaque = false
    self.backgroundColor = UIColor.clear
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    isAnimated = true
    rotate1()
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    isAnimated = false
    endRotation()
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    isAnimated = false
    endRotation()
}

override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else {return}
    context.addEllipse(in: rect)
    context.setLineWidth(1.0)
    context.setStrokeColor(UIColor.black.cgColor)
    context.setFillColor(UIColor.red.cgColor)
    context.drawPath(using: .fillStroke)
}

func rotate1() {
    guard isAnimated else { return }
    UIView.animate(withDuration: 0.05, delay:0.0, options: [], animations: {
        self.transform = CGAffineTransform.init(rotationAngle:.pi/16).scaledBy(x: 1.5, y: 1.5)
    }, completion: { _ in
        self.rotate2()
    })
}

func rotate2() {
    guard isAnimated else { return }
    UIView.animate(withDuration: 0.05, delay:0.0, options: [], animations: {
        self.transform = CGAffineTransform.init(rotationAngle:.pi/(-16)).scaledBy(x: 1.5, y: 1.5)
    }, completion: { _ in
        self.rotate1()
    })

}
func endRotation () {
    // End existing animation
    UIView.animate(withDuration: 0.5, delay:0.0, options: .beginFromCurrentState, animations: {
        self.transform = CGAffineTransform.init(rotationAngle:0 ).scaledBy(x: 1, y: 1)
    }, completion: nil)
}
}

对于这个版本,这里有一些位置显示

Pan began point (233.749182687299, 195.746572421573)
Pan changed point (175.265022520054, 181.332358181369)
Pan changed point (177.265022520054, 184.332358181369)
Pan changed point (177.265022520054, 184.332358181369)
Pan changed point (178.265022520054, 185.332358181369)
Pan changed point (179.265022520054, 186.332358181369)
Pan changed point (180.265022520054, 187.332358181369)
Pan changed point (180.265022520054, 188.332358181369)
Pan changed point (181.265022520054, 188.332358181369)
Pan RecognizedPan ended point (181.265022520054, 189.332358181369)

您可以看到第一个位置(起点)不正确:视图在那一刻被动画化了。其他位置都可以,拖动时,视图不会设置动画。

如果我在rotate1和rotate2中注释代码,则所有位置都是正确的,因此我假设视图的大小调整和最终旋转会干扰结果。我的问题是:当缩放视图时,如何检索视图的正确位置?显然,行

  

senderView.convert(senderView.center,to:nil)

没有做出我的想法:将坐标转换为固定大小的屏幕坐标?

2 个答案:

答案 0 :(得分:0)

我尝试将动画从View动画更改为Core Animation(图层),结果相同。

所以我试图想象一个公式,包括大小,边界和框架值,这可能会导致正确的位置,但我没有成功......

唯一有用的想法就是在尝试检索中心之前立即停止变换动画,就像在panView中那样

func panView(sender: UIPanGestureRecognizer) {
    guard let senderView = sender.view else { return }

    // Stop the transformation now!
    senderView.transform = CGAffineTransform.init(rotationAngle:0 ).scaledBy(x: 1, y: 1)

    if sender.state == .recognized { print("Pan Recognized", terminator:"")}
    ...

这不是我想要的解决方案,但我现在就要解决这个问题......

答案 1 :(得分:0)

事实上,我在视图转换中遇到了另一个问题(Retrieve the right position of a subView with auto-layout) 我的问题是一样的,所以解决方案就在这里......

我没有正确使用该方法。如果我使用beninho85的解决方案进行更改(以及更简洁的cosyn方法只使用一个视图),它就可以了!即使视图是动画的,我也可以拥有正确的坐标。

我只需要在ViewController中替换:

  

让point = senderView.convert(senderView.center,to:nil)

  

让point = senderView.convert(CGPoint(x:senderView.bounds.midX,y:senderView.bounds.midY),to:nil)