首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIView bounds.applying但有旋转

UIView bounds.applying但有旋转
EN

Stack Overflow用户
提问于 2018-10-01 10:58:12
回答 3查看 737关注 0票数 6

我想在视图周围创建一个破折号边框,它可以被移动/旋转/缩放。

这是我的密码:

代码语言:javascript
复制
func addBorder() {        
    let f = selectedObject.bounds.applying(selectedObject.transform)
    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    borderView.frame = f
    borderView.center = selectedObject.center
    borderView.transform = CGAffineTransform(translationX: selectedObject.transform.tx, y: selectedObject.transform.ty)

    removeBorder() //remove old border

    let f2 = CGRect(x: 0, y: 0, width: borderView.frame.width, height: borderView.frame.height)
    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.frame = f2
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: f2).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}

看起来是这样的:

这并不坏,但我希望边界也被旋转,因为它可能会误导用户,因为触摸区域只在图像上。

我尝试将旋转应用于转换:

代码语言:javascript
复制
func addBorder() {        
    let f = selectedObject.bounds.applying(selectedObject.transform)
    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    borderView.frame = f
    borderView.center = selectedObject.center
    let rotation = atan2(selectedObject.transform.b, selectedObject.transform.a)

    borderView.transform = CGAffineTransform(rotationAngle: rotation).translatedBy(x: selectedObject.transform.tx, y: selectedObject.transform.ty)

    removeBorder() //remove old border

    let f2 = CGRect(x: 0, y: 0, width: borderView.frame.width, height: borderView.frame.height)
    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.frame = f2
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: f2).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}

但旋转后它看起来是这样的:

我怎么才能解决这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-11 10:02:47

尽管我已经接受了这个答案,因为它帮助我理解了这个问题,我发布了最后的答案,因为它更重要。我认为这对其他人是有帮助的,因为我在Stackoverflow或其他地方找不到这个解决方案。

其想法是创建一个边界与borderView相同的selectedObject。这是@Incredible_dev的解决方案,但是有一个问题:当borderView向任何方向缩放时,行本身就会延伸。我想保持线的大小,它只想在selectedObject附近。因此,我用从selectedObject中提取的比例来乘以selectedObject.transform的界。然后从selectedObject复制平移和旋转。

下面是最后的代码:

代码语言:javascript
复制
var borderView: UIView!
var selectedObject: UIView?

extension CGAffineTransform { //helper extension

    func getScale() -> CGFloat {
        return (self.a * self.a + self.c * self.c).squareRoot()
    }

    func getRotation() -> CGFloat {
        return atan2(self.b, self.a)
    }

}

func removeBorder() { //remove the older border
    if borderView != nil {
        borderView.removeFromSuperview()
    }
}

func addBorder() {
    guard let selectedObject = selectedObject else { return }

    removeBorder() //remove old border

    let t = selectedObject.transform
    let s = t.getScale()
    let r = t.getRotation()

    borderView = UIView(frame: CGRect(x: 0, y: 0, width: selectedObject.bounds.width * s, height: selectedObject.bounds.height * s)) //multiply bounds with selectedObject's scale
    dividerImageView.addSubview(borderView) //add borderView to the "scene"

    borderView.transform = CGAffineTransform(translationX: t.tx, y: t.ty).rotated(by: r) //copy translation and rotation, order is important
    borderView.center = selectedObject.center

    let dashedBorder = CAShapeLayer() //create 2-point wide dashed line
    dashedBorder.lineWidth = 2
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: borderView.bounds).cgPath
    borderView.layer.addSublayer(dashedBorder)
}
票数 0
EN

Stack Overflow用户

发布于 2018-10-01 12:01:03

下面是一个基于您的代码的示例,应该这样做:

代码语言:javascript
复制
//initial transforms
selectedObject.transform = CGAffineTransform.init(rotationAngle: .pi / 4).translatedBy(x: 150, y: 15)

func addBorder() {
    let borderView = UIView.init(frame: selectedObject.bounds)
    self.view.addSubview(borderView)
    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    borderView.center = selectedObject.center
    borderView.transform = selectedObject.transform

    removeBorder() //remove old border

    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: borderView.bounds).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}
票数 2
EN

Stack Overflow用户

发布于 2018-10-10 09:14:53

以下是for问题的解决方案:

代码语言:javascript
复制
func addBorder() {

    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    let degrees: CGFloat = 20.0 //the value in degrees for rotation
    let radians: CGFloat = degrees * (.pi / 180)
    borderView.transform = CGAffineTransform(rotationAngle: radians)

    removeBorder()

    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.frame = borderView.bounds
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(roundedRect: borderView.bounds, cornerRadius:0).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}

上面的代码是用Swift 4.2在Xcode 10中测试的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52589657

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档