简体   繁体   English

如何在矩形中绘制多个水平圆(UIButton或UIControl)Swift iOS

[英]How to draw multiple horizontally circles in rectangle (UIButton or UIControl) Swift iOS

How to draw about three circle in horizontally area with main and ring color in rectangle. 如何在水平区域中用矩形和主色绘制大约三个圆。 I need to create custom button with this circles, something like this: 我需要使用此圈子创建自定义按钮,如下所示:

在此处输入图片说明

Is there any good way to do this? 有什么好办法吗?

We can design such kind of views with UIStackView in very ease manner. 我们可以使用UIStackView轻松地设计这种视图。 Take a stackView, set its alignment to center , axis to horizontal and distribution to fill . 拿一个stackView,将其alignment设置为center ,将axishorizontal ,并将其distributionfill Create a UILabel/UIButton/UIImageView or even UIView and add rounded radius and border to it. 创建一个UILabel/UIButton/UIImageView甚至UIView并向其添加圆角半径和边框。 Finally, add those views to the main stackView. 最后,将这些视图添加到主stackView中。 Try this. 尝试这个。

override func viewDidLoad() {
    super.viewDidLoad()

    //Setup stackView
    let myStackView = UIStackView()
    myStackView.axis = .horizontal
    myStackView.alignment = .center
    myStackView.distribution = .fillEqually
    myStackView.spacing = 8
    view.addSubview(myStackView)

    //Setup circles
    let circle_1 = circleLabel()
    let circle_2 = circleLabel()
    let circle_3 = circleLabel()

    myStackView.addArrangedSubview(circle_1)
    myStackView.addArrangedSubview(circle_2)
    myStackView.addArrangedSubview(circle_3)

    myStackView.translatesAutoresizingMaskIntoConstraints = false
    myStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0).isActive = true
    myStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0).isActive = true
}

func circleLabel() -> UILabel {

    let label = UILabel()
    label.backgroundColor = UIColor.red
    label.layer.cornerRadius = 12.5
    label.layer.masksToBounds = true
    label.layer.borderColor = UIColor.orange.cgColor
    label.layer.borderWidth = 3.0

    label.widthAnchor.constraint(equalToConstant: 25.0).isActive = true
    label.heightAnchor.constraint(equalToConstant: 25.0).isActive = true

    return label
}

在此处输入图片说明

Best and Universal Solution for **Button or Label creation (Fully Dynamic)** **创建按钮标签 (完全动态)的最佳和通用解决方案 **

var x = 10
    var y = 5
    var buttonHeight = 40
    var buttonWidth = 40

    for i in 0..<3  {
        let roundButton = UIButton(frame: CGRect(x: x, y: y, width: buttonWidth, height: buttonHeight))
        roundButton.setTitle("Butt\(i)", for: .normal)
        roundButton.layer.cornerRadius = roundButton.bounds.size.height/2
        yourButtonBackView.addSubview(roundButton)
        x = x + buttonWidth + 10
        if x >= Int(yourButtonBackView.frame.width - 30) {
            y = y + buttonHeight + 10
            x = 10
        }
    }

Сode: Сode:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let buttonSize: CGFloat = 80

        let firstButton = CustomButton(position: CGPoint(x: 0, y: 0), size: buttonSize, color: .blue)
        self.view.addSubview(firstButton)

        let secondButton = CustomButton(position: CGPoint(x: firstButton.frame.maxX, y: 0), size: buttonSize, color: .blue)
        self.view.addSubview(secondButton)

        let thirdButton = CustomButton(position: CGPoint(x: secondButton.frame.maxX, y: 0), size: buttonSize, color: .green)
        self.view.addSubview(thirdButton) 
    }

}


class CustomButton: UIButton {

    init(position: CGPoint, size: CGFloat, color: UIColor) {
        super.init(frame: CGRect(x: position.x, y: position.y, width: size, height: size))
        self.backgroundColor = color
        self.layer.cornerRadius = size / 2
        self.clipsToBounds = true
        self.layer.borderWidth = 4.0 // make it what ever you want
        self.layer.borderColor = UIColor.white.cgColor
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }
}

You can handle button tapped like: 您可以像这样处理轻按的按钮:

override func viewDidLoad() {
    super.viewDidLoad()
    firstButton.addTarget(self, action: #selector(handleFirstButton), for: .touchUpInside)
}
@objc func handleFirstButton(sender: UIButton) {
    print("first button tapped")
}

To make a Single Circle like that, you need to make use of UIBezierPath and CAShapeLayer . 要使像这样的单个圆 ,您需要使用UIBezierPathCAShapeLayer

 let outerCirclePath = UIBezierPath(arcCenter: CGPoint(x: 100,y: 100), radius: CGFloat(50), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)

    let outerCircleShapeLayer = CAShapeLayer()
    outerCircleShapeLayer.path = outerCirclePath.cgPath

    outerCircleShapeLayer.fillColor = UIColor.white.cgColor

    outerCircleShapeLayer.lineWidth = 3.0

    view.layer.addSublayer(outerCircleShapeLayer)

    // Drawing the inner circle
    let innerCirclePath = UIBezierPath(arcCenter: CGPoint(x: 100,y: 100), radius: CGFloat(40), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)

    let innerCircleShapeLayer = CAShapeLayer()
    innerCircleShapeLayer.path = innerCirclePath.cgPath

    innerCircleShapeLayer.fillColor = UIColor.blue.cgColor

    view.layer.addSublayer(innerCircleShapeLayer)

I have attached an image below for the Playground version of it . 我已经在下面附上了Playground版本的图片。

在此处输入图片说明

Just play around with arcCenter and radius values and you will get the desired output 只需使用arcCenterradius值,您将获得所需的输出

My lead helped me and here is solution to create this with dynamically changing state of circles (with different stroke and fill colors): 我的领导帮助了我,这是解决方案,可以通过动态改变圆的状态(具有不同的笔触和填充颜色)来创建此方案:

import UIKit

@IBDesignable
class CirclesButton: UIControl {

@IBInspectable
var firstCircle: Bool = false {
    didSet {
        setNeedsDisplay()
    }
}

@IBInspectable
var secondCircle: Bool = false {
    didSet {
        setNeedsDisplay()
    }
}

@IBInspectable
var thirdCircle: Bool = false {
    didSet {
        setNeedsDisplay()
    }
}

override func draw(_ rect: CGRect) {
    // get context
    guard let context = UIGraphicsGetCurrentContext() else { return }

    // make configurations
    context.setLineWidth(1.0);
    context.setStrokeColor(UIColor.white.cgColor)
    context.setFillColor(red: 0.0, green: 0.58, blue: 1.0, alpha: 1.0)

    // find view center
    let dotSize:CGFloat = 11.0
    let viewCenter = CGPoint(x: rect.midX, y: rect.midY)

    // find personal dot rect
    var dotRect = CGRect(x: viewCenter.x - dotSize / 2.0, y: viewCenter.y - dotSize / 2.0, width: dotSize, height: dotSize)

    if secondCircle {
        context.fillEllipse(in: dotRect)
    }
    context.strokeEllipse(in: dotRect)


    // find global notes rect
    dotRect = CGRect(x: viewCenter.x - dotSize * 1.5 - 4.0, y: viewCenter.y - dotSize / 2.0, width: dotSize, height: dotSize)
    if firstCircle {
        context.fillEllipse(in: dotRect)
    }
    context.strokeEllipse(in: dotRect)

    // find music rect
    dotRect = CGRect(x: viewCenter.x + dotSize / 2.0 + 4.0, y: viewCenter.y - dotSize / 2.0, width: dotSize, height: dotSize)
    if thirdCircle {
        context.setFillColor(red: 0.0, green: 1.0, blue: 0.04, alpha: 1.0)
        context.fillEllipse(in: dotRect)
    }
    context.strokeEllipse(in: dotRect)
}
}

I will looks like: CirclesButton 我将看起来像: CirclesButton

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM