churabou / swift-snippet

0 stars 0 forks source link

回転しても四隅にくっつく丸 #5

Open churabou opened 6 years ago

churabou commented 6 years ago
import SnapKit

protocol CircleButtonDelegate: class {
    func didSelectCircle()
}

class DeleteCircle: UIView {
    weak var delegate: CircleButtonDelegate?

    private var longPress = UILongPressGestureRecognizer()
    @objc private func actionTap() {
        delegate?.didSelectCircle()
    }

    func configure(view: UIView, delegate: CircleButtonDelegate) {
        self.delegate = delegate
        view.superview?.addSubview(self)
        let S: CGFloat = 30
        frame.size = CGSize(width: S, height: S)
        layer.cornerRadius = S/2
        clipsToBounds = true
        backgroundColor = .green
        longPress = UILongPressGestureRecognizer(target: self, action: #selector(actionTap))
        addGestureRecognizer(longPress)
    }
}

class ViewController: UIViewController {

    var blue = UIView()

    var rotateAngle: CGFloat = 0
    let circle = DeleteCircle()

    var rect: CGRect!

    override func viewDidLoad() {

        blue.backgroundColor = .blue
        view.addSubview(blue)
        rect = CGRect(x: 100, y: 100, width: 200, height: 100)
        blue.frame = rect

        circle.configure(view: blue, delegate: self)

        let origin = blue.frame.edges.bottomLeft
        circle.frame.origin = CGPoint(x: origin.x-30/2, y: origin.y-30/2)
        print("rotate: \(rect.rotatedEdges(by: 30))")
//        blue.transform = blue.transform.rotated(by: (-30*CGFloat.pi) / 180)
    }
}

extension ViewController: CircleButtonDelegate {

    func didSelectCircle() {
        rotateAngle += 1
        blue.transform = blue.transform.rotated(by: (1*CGFloat.pi) / 180)

        let origin = rect.rotatedEdges(by: Double(-rotateAngle)).bottomLeft
        circle.frame.origin = CGPoint(x: origin.x-30/2, y: origin.y-30/2)

    }
}

struct Math {

    static func sin(_ degrees: Double) -> CGFloat {
        return CGFloat(__sinpi(degrees/180.0))
    }

    static func cos(_ degrees: Double) -> CGFloat {
        return CGFloat(__cospi(degrees/180.0))
    }
}

extension CGRect {

    struct Edge {
        var topLeft: CGPoint
        var topRight: CGPoint
        var bottomLeft: CGPoint
        var bottomRight: CGPoint

        init(_ topLeft: CGPoint,
             _ topRight: CGPoint,
             _ bottomLeft: CGPoint,
             _  bottomRight: CGPoint) {
            self.topLeft = topLeft
            self.topRight = topRight
            self.bottomLeft = bottomLeft
            self.bottomRight = bottomRight
        }

        func dump() {
            print("topLeft \(topLeft)")
            print("topRight \(topRight)")
            print("bottomLeft \(bottomLeft)")
            print("bottomRight \(bottomRight)")
        }

        mutating func inverseY() {
            self.topLeft.y *= -1
            self.topRight.y *= -1
            self.bottomLeft.y *= -1
            self.bottomRight.y *= -1
        }
    }

    var edges: Edge {
        let topLeft = CGPoint(x: minX, y: minY)
        let topRight = CGPoint(x: maxX, y: minY)
        let bottomLeft = CGPoint(x: minX, y: maxY)
        let bottomRight = CGPoint(x: maxX, y: maxY)

        return Edge(topLeft, topRight, bottomLeft, bottomRight)
    }

    func rotatedEdges(by: Double) -> Edge {

        print("最初")
        edges.dump()
        //まず中心を原点に持ってくる。

        var rect = self
        let dif = CGPoint(x: midX, y: midY)

        rect.origin.x -= dif.x
        rect.origin.y -= dif.y

        print("中心に持ってきた")
        rect.edges.dump()

        var edge = rect.edges

        print("座標系を修正")
        edge.inverseY()
        edge.dump()

        print("回転")

        edge.topLeft = edge.topLeft.rotate(by: by)
        edge.topRight = edge.topRight.rotate(by: by)
        edge.bottomLeft = edge.bottomLeft.rotate(by: by)
        edge.bottomRight = edge.bottomRight.rotate(by: by)

        edge.dump()

        print("元に戻す")
        edge.inverseY()

        edge.topLeft.diff(dif)
        edge.topRight.diff(dif)
        edge.bottomLeft.diff(dif)
        edge.bottomRight.diff(dif)

        edge.dump()

        return edge
    }

}

fileprivate extension CGPoint {

    func rotate(by: Double) -> CGPoint { //x座標
        return CGPoint(x: x * Math.cos(by) - y * Math.sin(by),
                       y: x * Math.sin(by) + y * Math.cos(by))
    }

    mutating func diff(_ point: CGPoint) {
        x += point.x
        y += point.y
    }
}
churabou commented 6 years ago

ラベル

   func increaseFontSize(_ newBounds: CGRect) {

        var fontSize: CGFloat = label.fontSize
        var attributedText = NSAttributedString(string: label.text!,
                                                attributes: [.font: UIFont(name: label.font.fontName, size: fontSize) as Any])

        let size = CGSize(width: CGFloat.greatestFiniteMagnitude,
                          height: CGFloat.greatestFiniteMagnitude)

        var requiredSize = attributedText.boundingRect(with: size, options: [], context: nil)

        while requiredSize.width < newBounds.width {

            fontSize += 0.5
            attributedText = NSAttributedString(string: label.text!, attributes: [.font:
                UIFont(name: label.font.fontName, size: fontSize) as Any])
            requiredSize = attributedText.boundingRect(with: size, options: [], context: nil)
        }

        label.updateFontsize(to: fontSize)
    }