2017-10-09 54 views
0

enter image description here檢索在變換X爲邊緣

欲計算邊緣的x位置(左上,右上,左下和右下),其具有目前一個CGAffineTransformation一個UIView的用rotationAngle激活。在圖片中,我想計算最右邊紅圈的x位置。

本文介紹如何在Obj-c中執行此操作,我相信:http://www.informit.com/articles/article.aspx?p=1951182。我試圖將其轉換爲swift 4,但我不得不做出很多更改。我來到這個:

func offsetPoint(toParentCoordinates aPoint: CGPoint) -> CGPoint { 
    return CGPoint(x: aPoint.x + self.cardView.center.x, y: aPoint.y + self.cardView.center.y) 
} 

func point(inViewCenterTerms aPoint: CGPoint) -> CGPoint { 
    return CGPoint(x: aPoint.x - self.cardView.center.x, y: aPoint.y - self.cardView.center.y) 
} 

func point(inTransformedView aPoint: CGPoint, someTransformation: CGAffineTransform) -> CGPoint { 
    let offsetItem: CGPoint = point(inViewCenterTerms: aPoint) 
    let updatedItem: CGPoint = offsetItem.applying(someTransformation) 
    let finalItem: CGPoint = offsetPoint(toParentCoordinates: updatedItem) 
    return finalItem 
} 

func originalFrame(someView: UIView, someTransformation: inout CGAffineTransform) -> CGRect { 
    let currentTransform: CGAffineTransform = someTransformation 
    someTransformation = CGAffineTransform.identity 
    let originalFrame: CGRect = someView.frame 
    someTransformation = currentTransform 
    return originalFrame 
} 

但我被困在其餘的。我在想,如果Swift 4中的事情變得更簡單,或者如何繼續其餘的代碼來使其工作。

+0

您是否嘗試過使用簡單的座標計算:let x = r * sin(angle)並設y = r * cos(angle)? r是半徑,在你的情況下,它是對角線的一半長度。 – Woof

回答

1

我需要這個功能對我自己的項目之一,也是,所以我寫了一個基於由埃裏卡喪盾的對象 - 這個代碼UIView擴展你鏈接到你的問題:

extension UIView { 

    /// Returns the frame without any transformations 
    var originalFrame: CGRect { 

     let currentTransform = self.transform 
     self.transform = CGAffineTransform.identity 
     let frame = self.frame 
     self.transform = currentTransform 

     return frame 
    } 

    /// Returns the offset of the given point from the view center 
    func centerOffset(from point: CGPoint) -> CGPoint { 
     return CGPoint(x: point.x - center.x, y: point.y - center.y) 
    } 

    /// Returns the point relative to the view center by the given offset 
    func pointRelativeToCenter(by offset: CGPoint) -> CGPoint { 
     return CGPoint(x: offset.x + center.x, y: offset.y + center.y) 
    } 

    /// Returns the given point in transformed coordinates 
    func newPointInView(point: CGPoint) -> CGPoint { 

     let offset = self.centerOffset(from: point) 
     let transformedOffset = offset.applying(self.transform) 

     return self.pointRelativeToCenter(by: transformedOffset) 
    } 

    // Helpers to get the new View corner coordinates 

    var newTopLeft: CGPoint { 
     let frame = self.originalFrame 
     return self.newPointInView(point: frame.origin) 
    } 

    var newTopRight: CGPoint { 
     let frame = self.originalFrame 
     var point = frame.origin 
     point.x += frame.size.width 
     return self.newPointInView(point: point) 
    } 

    var newBottomLeft: CGPoint { 
     let frame = self.originalFrame 
     var point = frame.origin 
     point.y += frame.size.height 
     return self.newPointInView(point: point) 
    } 

    var newBottomRight: CGPoint { 
     let frame = self.originalFrame 
     var point = frame.origin 
     point.x += frame.size.width 
     point.y += frame.size.height 
     return self.newPointInView(point: point) 
    } 
} 

現在你可以簡單地訪問應用了CGAffineTransform的任何UIView上的newTopLeft,newTopRight,newBottomLeftnewBottomRight屬性,以便獲得變換視圖在父空間中的各個角位置。

這裏有一個小操場例子來演示如何使用擴展:

import UIKit 
import PlaygroundSupport 

// Setting up some example views 
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) 
containerView.backgroundColor = .white 
PlaygroundPage.current.liveView = containerView 

let transformedView = UIView(frame: CGRect(x: 150, y: 150, width: 200, height: 200)) 
transformedView.backgroundColor = .clear 
transformedView.layer.borderWidth = 3 
transformedView.layer.cornerRadius = 2 
containerView.addSubview(transformedView) 

// Add a rotation 
let angle = CGFloat.pi/4 
transformedView.transform = CGAffineTransform(rotationAngle: -angle) 

print(transformedView.newTopLeft) // assuming you've inserted the extension into the Playground somewhere above this line 

enter image description here

print(transformedView.newTopLeft)然後將輸出

(108.57864376269, 250.0) 

你可以使用一些簡單的三角函數檢查值是正確的。

+0

Thx bro。雖然我有這條線的問題:PlaygroundPage.current.liveView = containerView,我在VC中測試它。有效 :)。由於限制,我可以在幾個小時內獎賞賞金。 – NoKey

+0

@JasperVisser哦,對!你需要'導入PlaygroundSupport'來使實時查看工作。我忘了複製那一行。 – Keiwan