ios - 在任意位置画圆

标签 ios swift

问题如下: 1.需要在屏幕上任意位置实现圆圈。 2. 圆必须是不同的半径,不能相互重叠,不能超出屏幕。

为 View 创建了一个单独的文件。这是代码:

override func draw(_ rect: CGRect) {

    var number = 1

    while number <= 5 {
        //1. Screen center coordinates
        let viewMidX = self.bounds.size.height
        let viewMidY = self.bounds.size.width

        //2. Circle radius
        let circleWidth = CGFloat(20 + arc4random_uniform(30))
        let circleHeight = circleWidth

        //3. Two random number
        let randomNumberOne = CGFloat(arc4random_uniform(40))
        let randomNumberTwo = CGFloat(arc4random_uniform(20))

        //4. Coordinates and sizes of the circle
        let rect = CGRect(x: viewMidX - randomNumberOne , y: viewMidY - randomNumberTwo , width: circleWidth, height: circleHeight)

        //5. Draw circle
        let circlePath = UIBezierPath(roundedRect: rect, cornerRadius: circleWidth / 2)

        //6. Circle color
        myColor.setFill()
        circlePath.fill()


        myColor.setStroke()
        circlePath.stroke()

        number += 1
    }

在 ViewController 文件中,我正在为这个圆做一些动画(脉冲)

//7.
    self.view.transform = CGAffineTransform(scaleX: 1, y: 1)

    //8. Animation
    UIView.animateKeyframes(withDuration: 1, delay: 0, options: [.autoreverse, .repeat], animations: {
        self.view.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
    }) { finished in
    }

当我开始时,我画了 1 个圆圈,仅此而已。

enter image description here

最佳答案

有一些明显的错误。

让 viewMidX = self.bounds.size.height

应该是

让 viewMidX = self.bounds.size.width/2

viewMidY 做类似的事情

接下来查看您为其设置随机数的距离,移动是最小的。 (40 和 20) 下面的图片表示应该在何处绘制圆圈。

enter image description here

所以我推荐的是更像这样的东西。

import UIKit

class ViewController: UIViewController {

    let circleView = CircleView()
    let tapView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(circleView)
        view.addSubview(tapView)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        circleView.frame = view.frame
        tapView.frame = view.frame
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        animate()
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)
        circleView.setNeedsDisplay()
    }

    // Animation
    func animate() {
        UIView.animateKeyframes(withDuration: 1, delay: 0, options: [.autoreverse, .repeat], animations: {
            self.circleView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
        }, completion: nil)
    }

}

class CircleView: UIView {

    var myColor = UIColor.red
    var borderColor = UIColor.black
    var usedRects: [CGRect] = []
    var usedDiameters: [CGFloat] = []

    init() {
        super.init(frame: .zero)
        backgroundColor = .lightGray
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)
        setNeedsDisplay()
    }

    override func draw(_ rect: CGRect) {
        usedRects = []
        usedDiameters = []
        for _ in 0..<5 {

            //1. Circle Diameter
            let diameter = getDiameter()

            //2. Circle Rect
            let rect = getRect(diameter: diameter)

            //3. Circle Path
            let circlePath = UIBezierPath(roundedRect: rect, cornerRadius: diameter / 2)

            //4. Circle Color
            myColor.setFill()

            //5. Draw Circle
            circlePath.fill()

            //6. Circle Border Color
            borderColor.setStroke()

            //7. Draw Circle Boder
            circlePath.stroke()
        }
    }

    func getDiameter() -> CGFloat {
        let diameter = CGFloat(20 + arc4random_uniform(30))
        for usedDiameter in usedDiameters
            where usedDiameter == diameter {
                return getDiameter()
        }
        usedDiameters.append(diameter)
        return diameter
    }

    func getRect(diameter: CGFloat) -> CGRect {
        let randomWidth = CGFloat(arc4random_uniform(UInt32(self.bounds.size.width)))
        let randomHeight = CGFloat(arc4random_uniform(UInt32(self.bounds.size.height)))

        let rect = CGRect(x: randomWidth, y: randomHeight, width: diameter, height: diameter)

        for usedRect in usedRects
            where usedRect.intersects(rect) {
                return getRect(diameter: diameter)
        }
        usedRects.append(rect)
        return rect
    }

}

关于ios - 在任意位置画圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53445727/

相关文章:

ios - 如何使用动态 View iOS Swift 处理导航?

ios - 如何在 launchScreen 之后建立引导?

swift - 限制在 Swift 语言的文本字段中输入某些第一个/初始值

ios - 如何使用嵌套的 NSDate 属性将 Realm 对象转换为 JSON?

javascript - 我应该用哪种方法注入(inject)javascript? (stringByEvaluatingJavaScriptFromString)

ios - 缓存图像以供离线使用 SDWebImage

ios - 如何在 Swift Alamofire 中使用 ssl 证书?

ios - Alamofire - 调用中的额外参数 'method'

swift - 添加触摸开始处的节点

swift - 在 URLSession 闭包中调用委托(delegate)方法时崩溃