let block = UIView(frame: CGRectMake(cellWidth-25, cellHeight/2-8, 16, 16))
block.backgroundColor = UIColor(netHex: 0xff3b30)
block.layer.cornerRadius = 9
block.clipsToBounds = true
Das ist es, was ich gerade habe, aber es ist offensichtlich nicht der richtige Weg, es zu tun.
Was ist der einfachste Weg, dies zu tun?
Antworten:
Sie können damit einen Kreis zeichnen ( Swift 3.0+ ):
let circlePath = UIBezierPath(arcCenter: CGPoint(x: 100, y: 100), radius: CGFloat(20), startAngle: CGFloat(0), endAngle: CGFloat(Double.pi * 2), clockwise: true) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.cgPath // Change the fill color shapeLayer.fillColor = UIColor.clear.cgColor // You can change the stroke color shapeLayer.strokeColor = UIColor.red.cgColor // You can change the line width shapeLayer.lineWidth = 3.0 view.layer.addSublayer(shapeLayer)
Mit dem Code, den Sie gepostet haben, beschneiden Sie die Ecken von
UIView
und fügen der Ansicht keinen Kreis hinzu.Hier ist ein vollständiges Beispiel für die Verwendung dieser Methode:
/// A special UIView displayed as a ring of color class Ring: UIView { override func drawRect(rect: CGRect) { drawRingFittingInsideView() } internal func drawRingFittingInsideView() -> () { let halfSize:CGFloat = min( bounds.size.width/2, bounds.size.height/2) let desiredLineWidth:CGFloat = 1 // your desired value let circlePath = UIBezierPath( arcCenter: CGPoint(x:halfSize,y:halfSize), radius: CGFloat( halfSize - (desiredLineWidth/2) ), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.CGPath shapeLayer.fillColor = UIColor.clearColor().CGColor shapeLayer.strokeColor = UIColor.redColor().CGColor shapeLayer.lineWidth = desiredLineWidth layer.addSublayer(shapeLayer) } }
Beachten Sie jedoch, dass es einen unglaublich praktischen Anruf gibt:
let circlePath = UIBezierPath(ovalInRect: rect)
das macht die ganze Arbeit, den Weg zu machen. (Vergessen Sie nicht, es für die Linienstärke einzufügen, was auch mit unglaublich einfach ist
CGRectInset
.)internal func drawRingFittingInsideView(rect: CGRect) { let desiredLineWidth:CGFloat = 4 // Your desired value let hw:CGFloat = desiredLineWidth/2 let circlePath = UIBezierPath(ovalInRect: CGRectInset(rect,hw,hw)) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.CGPath shapeLayer.fillColor = UIColor.clearColor().CGColor shapeLayer.strokeColor = UIColor.redColor().CGColor shapeLayer.lineWidth = desiredLineWidth layer.addSublayer(shapeLayer) }
In der Praxis dieser Tage in Swift würden Sie sicherlich
@IBDesignable
und verwenden@IBInspectable
. Mit diesen können Sie tatsächlich das Rendering im Storyboard sehen und ändern!Wie Sie sehen können, werden dem Inspektor im Storyboard neue Funktionen hinzugefügt, die Sie im Storyboard ändern können:
/// A dot with a border, which you can control completely in Storyboard @IBDesignable class Dot: UIView { @IBInspectable var mainColor: UIColor = UIColor.blueColor() { didSet { print("mainColor was set here") } } @IBInspectable var ringColor: UIColor = UIColor.orangeColor() { didSet { print("bColor was set here") } } @IBInspectable var ringThickness: CGFloat = 4 { didSet { print("ringThickness was set here") } } @IBInspectable var isSelected: Bool = true override func drawRect(rect: CGRect) { let dotPath = UIBezierPath(ovalInRect:rect) let shapeLayer = CAShapeLayer() shapeLayer.path = dotPath.CGPath shapeLayer.fillColor = mainColor.CGColor layer.addSublayer(shapeLayer) if (isSelected) { drawRingFittingInsideView(rect) } } internal func drawRingFittingInsideView(rect: CGRect) { let hw:CGFloat = ringThickness/2 let circlePath = UIBezierPath(ovalInRect: CGRectInset(rect,hw,hw) ) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.CGPath shapeLayer.fillColor = UIColor.clearColor().CGColor shapeLayer.strokeColor = ringColor.CGColor shapeLayer.lineWidth = ringThickness layer.addSublayer(shapeLayer) } }
Beachten Sie schließlich, dass Sie, wenn Sie ein
UIView
(das quadratisch ist und das Sie im Storyboard auf rot setzen) haben und es einfach in einen roten Kreis verwandeln möchten, einfach Folgendes tun können:// Makes a UIView into a circular dot of color class Dot: UIView { override func layoutSubviews() { layer.cornerRadius = bounds.size.width/2 } }
quelle
M_PI
ist veraltet. Es ist jetztDouble.pi
(in Swift 3)func drawRect(rect: CGRect)
Methode in die Methode aufzunehmen, da diese Methode benutzerdefiniertes Zeichnen in einer eigenen Ebene ausführen soll. Diese Methode wird auch als mehrfach bezeichnet.Wenn Sie ein UIView zum Zeichnen verwenden möchten, müssen Sie den Radius / der Höhe oder Breite festlegen.
Also einfach ändern:
block.layer.cornerRadius = 9
zu:
block.layer.cornerRadius = block.frame.width / 2
Sie müssen jedoch Höhe und Breite gleich einstellen. Wenn Sie Koregraphik verwenden möchten, sollten Sie Folgendes tun:
CGContextRef ctx= UIGraphicsGetCurrentContext(); CGRect bounds = [self bounds]; CGPoint center; center.x = bounds.origin.x + bounds.size.width / 2.0; center.y = bounds.origin.y + bounds.size.height / 2.0; CGContextSaveGState(ctx); CGContextSetLineWidth(ctx,5); CGContextSetRGBStrokeColor(ctx,0.8,0.8,0.8,1.0); CGContextAddArc(ctx,locationOfTouch.x,locationOfTouch.y,30,0.0,M_PI*2,YES); CGContextStrokePath(ctx);
quelle
Erstellen Sie eine Klasse UIView und weisen Sie ihr diesen Code für einen einfachen Kreis zu
import UIKit @IBDesignable class DRAW: UIView { override func draw(_ rect: CGRect) { var path = UIBezierPath() path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 100, height: 100)) UIColor.yellow.setStroke() UIColor.red.setFill() path.lineWidth = 5 path.stroke() path.fill() } }
quelle
Swift 4- Version der akzeptierten Antwort:
@IBDesignable class CircledDotView: UIView { @IBInspectable var mainColor: UIColor = .white { didSet { print("mainColor was set here") } } @IBInspectable var ringColor: UIColor = .black { didSet { print("bColor was set here") } } @IBInspectable var ringThickness: CGFloat = 4 { didSet { print("ringThickness was set here") } } @IBInspectable var isSelected: Bool = true override func draw(_ rect: CGRect) { let dotPath = UIBezierPath(ovalIn: rect) let shapeLayer = CAShapeLayer() shapeLayer.path = dotPath.cgPath shapeLayer.fillColor = mainColor.cgColor layer.addSublayer(shapeLayer) if (isSelected) { drawRingFittingInsideView(rect: rect) } } internal func drawRingFittingInsideView(rect: CGRect) { let hw: CGFloat = ringThickness / 2 let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw, dy: hw)) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.cgPath shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = ringColor.cgColor shapeLayer.lineWidth = ringThickness layer.addSublayer(shapeLayer) } }
quelle
Aktualisierung des Code-Ansatzes von @ Dario für Xcode 8.2.2, Swift 3.x. Stellen Sie im Storyboard fest, dass die Hintergrundfarbe auf "klar" gesetzt ist, um einen schwarzen Hintergrund in der quadratischen UIView zu vermeiden:
import UIKit @IBDesignable class Dot:UIView { @IBInspectable var mainColor: UIColor = UIColor.clear { didSet { print("mainColor was set here") } } @IBInspectable var ringColor: UIColor = UIColor.clear { didSet { print("bColor was set here") } } @IBInspectable var ringThickness: CGFloat = 4 { didSet { print("ringThickness was set here") } } @IBInspectable var isSelected: Bool = true override func draw(_ rect: CGRect) { let dotPath = UIBezierPath(ovalIn: rect) let shapeLayer = CAShapeLayer() shapeLayer.path = dotPath.cgPath shapeLayer.fillColor = mainColor.cgColor layer.addSublayer(shapeLayer) if (isSelected) { drawRingFittingInsideView(rect: rect) } } internal func drawRingFittingInsideView(rect: CGRect)->() { let hw:CGFloat = ringThickness/2 let circlePath = UIBezierPath(ovalIn: rect.insetBy(dx: hw,dy: hw) ) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.cgPath shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = ringColor.cgColor shapeLayer.lineWidth = ringThickness layer.addSublayer(shapeLayer) } }
Und wenn Sie den Start- und Endwinkel steuern möchten:
import UIKit @IBDesignable class Dot:UIView { @IBInspectable var mainColor: UIColor = UIColor.clear { didSet { print("mainColor was set here") } } @IBInspectable var ringColor: UIColor = UIColor.clear { didSet { print("bColor was set here") } } @IBInspectable var ringThickness: CGFloat = 4 { didSet { print("ringThickness was set here") } } @IBInspectable var isSelected: Bool = true override func draw(_ rect: CGRect) { let dotPath = UIBezierPath(ovalIn: rect) let shapeLayer = CAShapeLayer() shapeLayer.path = dotPath.cgPath shapeLayer.fillColor = mainColor.cgColor layer.addSublayer(shapeLayer) if (isSelected) { drawRingFittingInsideView(rect: rect) } } internal func drawRingFittingInsideView(rect: CGRect)->() { let halfSize:CGFloat = min( bounds.size.width/2, bounds.size.height/2) let desiredLineWidth:CGFloat = ringThickness // your desired value let circlePath = UIBezierPath( arcCenter: CGPoint(x: halfSize, y: halfSize), radius: CGFloat( halfSize - (desiredLineWidth/2) ), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi), clockwise: true) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.cgPath shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = ringColor.cgColor shapeLayer.lineWidth = ringThickness layer.addSublayer(shapeLayer) } }
quelle
Ich finde Core Graphics für Swift 3 ziemlich einfach :
if let cgcontext = UIGraphicsGetCurrentContext() { cgcontext.strokeEllipse(in: CGRect(x: center.x-diameter/2, y: center.y-diameter/2, width: diameter, height: diameter)) }
quelle
Eine einfache Funktion, die einen Kreis in der Mitte Ihres Fensterrahmens mit einem Multiplikatorprozentsatz zeichnet
/// CGFloat is a multiplicator from self.view.frame.width func drawCircle(withMultiplicator coefficient: CGFloat) { let radius = self.view.frame.width / 2 * coefficient let circlePath = UIBezierPath(arcCenter: self.view.center, radius: radius, startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true) let shapeLayer = CAShapeLayer() shapeLayer.path = circlePath.cgPath //change the fill color shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = UIColor.darkGray.cgColor shapeLayer.lineWidth = 2.0 view.layer.addSublayer(shapeLayer) }
quelle
In Ansicht hinzufügen wurde geladen
//Circle Points var CircleLayer = CAShapeLayer() let center = CGPoint (x: myCircleView.frame.size.width / 2, y: myCircleView.frame.size.height / 2) let circleRadius = myCircleView.frame.size.width / 2 let circlePath = UIBezierPath(arcCenter: center, radius: circleRadius, startAngle: CGFloat(M_PI), endAngle: CGFloat(M_PI * 4), clockwise: true) CircleLayer.path = circlePath.cgPath CircleLayer.strokeColor = UIColor.red.cgColor CircleLayer.fillColor = UIColor.blue.cgColor CircleLayer.lineWidth = 8 CircleLayer.strokeStart = 0 CircleLayer.strokeEnd = 1 Self.View.layer.addSublayer(CircleLayer)
quelle
Ein viel einfacherer und ressourcenschonender Ansatz wäre.
import UIKit @IBDesignable class CircleDrawView: UIView { @IBInspectable var borderColor: UIColor = UIColor.red; @IBInspectable var borderSize: CGFloat = 4 override func draw(_ rect: CGRect) { layer.borderColor = borderColor.cgColor layer.borderWidth = borderSize layer.cornerRadius = self.frame.height/2 } }
Mit
Border Color
undBorder Size
und der StandardeigenschaftBackground
können Sie das Erscheinungsbild des Kreises definieren.Bitte beachten Sie, dass zum Zeichnen eines Kreises die Höhe und Breite der Ansicht gleich groß sein müssen.
Der Code funktioniert für
Swift >= 4
undXcode >= 9
.quelle
Hier ist meine Version mit Swift 5 und Core Graphics.
Ich habe eine Klasse erstellt, um zwei Kreise zu zeichnen. Der erste Kreis wird mit erstellt
addEllipse()
. Es setzt die Ellipse in ein Quadrat und erzeugt so einen Kreis. Ich finde es überraschend, dass es keine Funktion gibtaddCircle()
. Der zweite Kreis wird mitaddArc()
2pi Bogenmaß erstelltimport UIKit @IBDesignable class DrawCircles: UIView { override init(frame: CGRect) { super.init(frame: frame) } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override func draw(_ rect: CGRect) { guard let context = UIGraphicsGetCurrentContext() else { print("could not get graphics context") return } context.setLineWidth(2) context.setStrokeColor(UIColor.blue.cgColor) context.addEllipse(in: CGRect(x: 30, y: 30, width: 50.0, height: 50.0)) context.strokePath() context.setStrokeColor(UIColor.red.cgColor) context.beginPath() // this prevents a straight line being drawn from the current point to the arc context.addArc(center: CGPoint(x:100, y: 100), radius: 20, startAngle: 0, endAngle: 2.0*CGFloat.pi, clockwise: false) context.strokePath() } }
Fügen Sie in Ihrem ViewController
didViewLoad()
Folgendes hinzu:let myView = DrawCircles(frame: CGRect(x: 50, y: 50, width: 300, height: 300)) self.view.addSubview(myView)
Wenn es läuft, sollte es so aussehen. Ich hoffe dir gefällt meine Lösung!
quelle