updating classes in swift - ios

I am looking for a solution to my problem. I have a class that creates a UIButton for me:
class MenuButton: UIButton {
var x: CGFloat
var y: CGFloat
var width: CGFloat
var height: CGFloat
required init(parent: UIView = UIView(), x: CGFloat = 0, y: CGFloat = 0, width: CGFloat = 40, height: CGFloat = 40) {
self.x = x
self.y = y
self.width = width
self.height = height
super.init(frame: .zero)
frame = CGRect(x: x, y: y, width: width, height: height)
backgroundColor = global.labelColor
setTitleColor(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), for: .normal)
layer.cornerRadius = self.frame.height / 2
if x < 0 {
frame = CGRect(x: superview?.frame.width ?? 0 - abs(x) - frame.width, y: frame.minY, width: frame.width, height: frame.height)
}
if y < 0 {
frame = CGRect(x: frame.minX, y: superview?.frame.height ?? 0 - abs(y) - frame.height, width: frame.width, height: frame.height)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Then I add a constant that is assigned to this class:
let pauseButton = MenuButton()
This works fine and the button is shown on the scene with everything to default. Now I want to add those things in the viewDidLoad() (I added the subview to acces it in the class):
view.addSubview(pauseButton)
pauseButton.x = -20
pauseButton.y = 20
pauseButton.width = 40
pauseButton.height = 40
This does not update the stuff I specified in the init(). How do I call the init again (without doing pauseButton = MenuButton() again) or is there like an update() I can use?
Thank you for your help ;)

You can actually pass those values in the initializer as below,
let pauseButton = MenuButton(parent: view, x: -20, y: 20, width: 40, height: 40)
If you want to make your button update immediately as you change any of these properties then you can use didSet callback to set the frame as below,
class MenuButton: UIButton {
var x: CGFloat {
didSet {
self.updateFrame()
}
}
var y: CGFloat {
didSet {
self.updateFrame()
}
}
var width: CGFloat {
didSet {
self.updateFrame()
}
}
var height: CGFloat {
didSet {
self.updateFrame()
}
}
private func updateFrame() {
frame = CGRect(x: x, y: y, width: width, height: height)
}
required init(parent: UIView = UIView(), x: CGFloat = 0, y: CGFloat = 0, width: CGFloat = 40, height: CGFloat = 40) {
self.x = x
self.y = y
self.width = width
self.height = height
super.init(frame: .zero)
frame = CGRect(x: x, y: y, width: width, height: height)
backgroundColor = .green
setTitleColor(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), for: .normal)
layer.cornerRadius = self.frame.height / 2
if x < 0 {
frame = CGRect(x: superview?.frame.width ?? 0 - abs(x) - frame.width, y: frame.minY, width: frame.width, height: frame.height)
}
if y < 0 {
frame = CGRect(x: frame.minX, y: superview?.frame.height ?? 0 - abs(y) - frame.height, width: frame.width, height: frame.height)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

each UIViewController have UIView accessed inside of it as view
you are adding the subview already here.
view.addSubview(pauseButton)
so just pass it into the init() you have and add it there.
your code could be something like this.
class MenuButton: UIButton {
var x: CGFloat
var y: CGFloat
var width: CGFloat
var height: CGFloat
required init(parent: UIView = UIView(), x: CGFloat = 0, y: CGFloat = 0, width: CGFloat = 40, height: CGFloat = 40) {
self.x = x
self.y = y
self.width = width
self.height = height
super.init(frame: .zero)
frame = CGRect(x: x, y: y, width: width, height: height)
backgroundColor = global.labelColor
setTitleColor(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), for: .normal)
layer.cornerRadius = self.frame.height / 2
if x < 0 {
frame = CGRect(x: superview?.frame.width ?? 0 - abs(x) - frame.width, y: frame.minY, width: frame.width, height: frame.height)
}
if y < 0 {
frame = CGRect(x: frame.minX, y: superview?.frame.height ?? 0 - abs(y) - frame.height, width: frame.width, height: frame.height)
}
parent.addSubview(self)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And use it in ViewDidLoad like this.
let _ = MenuButton(parent: view, x: -20, y: 20, width: 40, height: 40)

init() method is called only once when you instantiating your button. You should try to instantiate the button with the desired properties. Try something like this:
let pauseButton = MenuButton(parent: UIView(), x: -20, y: 20, width: 40, height:40)
Then in your viewDidLoad() method you can have just this line:
view.addSubview(pauseButton)
Another problem that I noticed is that you are referencing to the superview in your init() method, but superview is always nil in that case, since your button is not yet added as a subview.

have you tried ?
button.frame = CGRect(x:xPostion, y:yPostion, width:buttonWidth, height:buttonHeight)
or u can declare a funtion called updateFrame in ur Menu button class and pass new position as argument , like this :
func updateFrame(x:CGFloat, y: CGFloat, width: CGFloat, height: CGFloat){
self.frame = CGRect(x:xPostion, y:yPostion, width:buttonWidth, height:buttonHeight)
}
and in your VideDidLoad :
button.updateFrame(x:xPostion, y:yPostion, width:buttonWidth, height:buttonHeight)
what you are doing at the moment is just assigning some values to your Button's properties, how should your button knows to use them to reset its frame ??

Related

macOS NSScrollView Not Scrolling Vertically

I am trying to add few views to see if the NSScrollView will scroll vertically but it is not doing anything.
private func configure2() {
var yOffset = 0
let scrollView = NSScrollView(frame: NSRect(x: 0, y: 0, width: 400, height: 900))
scrollView.hasVerticalScroller = true
for _ in 1...20 {
let v = NSView(frame: NSRect(x: 0, y: 0 + yOffset, width: 50, height: 20))
v.wantsLayer = true
v.layer?.backgroundColor = NSColor.red.cgColor
scrollView.addSubview(v)
yOffset += 40
}
scrollView.backgroundColor = NSColor.green
self.addSubview(scrollView)
}
I remember in UIKit I can set the contentSize property of UIScrollView but in macOS I cannot set contentSize.
You need to set either the documentView or contentView of your NSScrollView. Then, you'll add your subviews to that view.
private func configure2() {
var yOffset = 0
let scrollView = NSScrollView(frame: NSRect(x: 0, y: 0, width: 400, height: 900))
let documentView = NSView(frame: .zero)
scrollView.hasVerticalScroller = true
for _ in 1...20 {
let v = NSView(frame: NSRect(x: 0, y: 0 + yOffset, width: 50, height: 20))
v.wantsLayer = true
v.layer?.backgroundColor = NSColor.red.cgColor
documentView.addSubview(v)
yOffset += 40
}
print(yOffset)
documentView.frame = .init(x: 0, y: 0, width: 400, height: yOffset)
scrollView.documentView = documentView
scrollView.backgroundColor = NSColor.green
self.addSubview(scrollView)
}

Alternative to Inheritance from multiple classes swift

I have a class that manages positioning of UIKit elements using 'frame':
class EasyPos: UIView {
var screenWidth = UIScreen.main.bounds.width
var screenHeight = UIScreen.main.bounds.height
var x: CGFloat = 0 { didSet { self.updateFrame() } }
var y: CGFloat = 0 { didSet { self.updateFrame() } }
var width: CGFloat = 0 { didSet { self.updateFrame() } }
var height: CGFloat = 0 { didSet { self.updateFrame() } }
func updateFrame() {
frame = CGRect(x: x, y: y, width: width, height: height)
if x < 0 {
frame = CGRect(x: screenWidth - abs(x) - width, y: frame.minY, width: frame.width, height: frame.height)
}
if y < 0 {
frame = CGRect(x: frame.minX, y: screenHeight - abs(y) - height, width: frame.width, height: frame.height)
}
}
required init(x: CGFloat = 0, y: CGFloat = 0, width: CGFloat = 40, height: CGFloat = 40) {
self.x = x
self.y = y
self.width = width
self.height = height
super.init(frame: .zero)
updateFrame()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Now I want to add one class that inherits from UIbutton and one that inherits from a UILabel. And they should both be able to use the methods from the EasyPos class. How do I do this? (I tried inheritance from two classes, didn't work)
I know it has something to do with protocols. But I couldn't get this to work either.
Thanks for you help ;)
One way you could do this is to write a protocol extension. Because you have properties you'll need to implement a component but it shouldn't be too difficult -
struct FrameComponent {
var x: CGFloat = 0
var y: CGFloat = 0
var width: CGFloat = 0
var height: CGFloat = 0
}
protocol EasyPos {
var fc: FrameComponent { get, set }
func updateFrame()
}
extension EasyPos where Self: UIView {
func updateFrame() {
frame = CGRect(x: fc.x, y: fc.y, width: fc.width, height: fc.height)
if fc.x < 0 {
frame = CGRect(x: screenWidth - abs(fc.x) - fc.width, y: frame.minY, width:
frame.width, height: frame.height)
}
if fc.y < 0 {
frame = CGRect(x: frame.minX, y: screenHeight - abs(fc.y) - fc.height, width:
frame.width, height: frame.height)
}
}
}
Something you should remember is extensions can't add property observers, so you will need to call updateFrame() manually.

Touch event on Visible Portion of Views ios swift 4

I am working of Photo Collage which is in Swift4 , I had created collage using UIBezierPath as Below
I have 5 scroll views in Storyboard and the sequence of Scrollviews as Below
Using Following code I am creating Shapes :
var path1 = UIBezierPath()
path1.move(to: CGPoint(x: 0, y: 0))
path1.addLine(to: CGPoint(x: superView.frame.width / 2, y: 0))
path1.addLine(to: CGPoint(x: 0, y: superView.frame.width / 2))
path1.addLine(to: CGPoint(x: 0, y: 0))
var borderPathRef1 = path1.cgPath
var borderShapeLayer1 = CAShapeLayer()
borderShapeLayer1.path = borderPathRef1
scroll1.layer.mask = borderShapeLayer1
scroll1.layer.masksToBounds = true
var path2 = UIBezierPath()
path2.move(to: CGPoint(x: 0, y: 0))
path2.addLine(to: CGPoint(x: superView.frame.width / 2, y: 0))
path2.addLine(to: CGPoint(x: superView.frame.width / 2, y: superView.frame.width / 2))
path2.addLine(to: CGPoint(x: 0, y: 0))
var borderPathRef2 = path2.cgPath
var borderShapeLayer2 = CAShapeLayer()
borderShapeLayer2.path = borderPathRef2
scroll2.layer.mask = borderShapeLayer2
scroll2.layer.masksToBounds = true
Now the issue is I am not able to get touch event of Scrollviews as Scroll5 is on top. I want to get Touch on Overlapped views like Scroll1, Scroll2 and so on. In Short I need touch event for particular view on the portion of area where the view is visible.
See The Image Below Where I want Touch for Views.
How can I get touch on Overlapped Views?
Please Help!
You have to be sure that you set the superView of scrollview to isUserInterfaceEnabled=true first.
To get overlapped views touch event:
here is my code:
class CustomView: UIView {
let view1: UIView
let view2: UIView
let view3: UIView
let view4: UIView
let view5: UIView
override init(frame: CGRect) {
view1 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view1.backgroundColor = UIColor.black
view1.isUserInteractionEnabled = true
view2 = UIView(frame: CGRect(x: 100, y: 0, width: 100, height: 100))
view2.backgroundColor = UIColor.orange
view2.isUserInteractionEnabled = true
view3 = UIView(frame: CGRect(x: 0, y: 100, width: 100, height: 100))
view3.backgroundColor = UIColor.blue
view3.isUserInteractionEnabled = true
view4 = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
view4.backgroundColor = UIColor.brown
view4.isUserInteractionEnabled = true
view5 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view5.tag = 121
view5.backgroundColor = UIColor.red
super.init(frame: frame)
self.addSubview(view1)
self.addSubview(view2)
self.addSubview(view3)
self.addSubview(view4)
self.addSubview(view5)
view1.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(touchAction)))
}
#objc func touchAction () {
print("----------- touch view 1")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if (view1.point(inside: self.convert(point, to: view1), with: event)) {
return view1
}
return self
}
}
The function hitTest decides that which view you are touching, so you just need to return the overlapped view.

IBDesignable - Arrange subviews added through interface builder

I am currently messing around with IBDesignable Views, and I am curious if anyone has been able to solve this. I would like to have views added through the interface builder be automatically arranged using a custom layout algorithm within my subview. The view works great when I run the app, but in the interface builder, the views do not rearrange in real time.
I have tried debugging my UIView class, but it seems at all times when the interface builder is initializing the element, it thinks it has zero subviews. It seems the interface builder does not give you a chance to arrange these views after the fact. However, I'm wondering if maybe there is just something I'm missing. Is it possible to rearrange subviews added from the interface builder within an IBDesignable class, and have the views show up rearranged in the interface builder?
Try using the provided method for a custom view and IBDesignable if you are not already. You also might need to refresh your views in Xcode or have it automatically refresh views. Below is the function you may be missing. This is never called in a live app. It is only called in Xcode IB.
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setUpView()
}
In this instance setUpView is laying out my subviews.
Here is an example that I made. https://github.com/agibson73/ICONButton
import UIKit
#IBDesignable class AGIconButton: UIControl {
private var iconImageView : UIImageView!
private var iconLabel : UILabel!
private var mainSpacer : UIView!
private var highlightView:UIView!
private var widthContraint : NSLayoutConstraint!
var padding : CGFloat = 5
override init(frame: CGRect) {
super.init(frame: frame)
setUpView()
addTarget(self, action: #selector(AGIconButton.userDidTouchDown), for: .touchDown)
addTarget(self, action: #selector(AGIconButton.userDidTouchUp), for: .touchUpInside)
addTarget(self, action: #selector(AGIconButton.userDidTouchUpOutside), for: .touchUpOutside)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpView()
addTarget(self, action: #selector(AGIconButton.userDidTouchDown), for: .touchDown)
addTarget(self, action: #selector(AGIconButton.userDidTouchUp), for: .touchUpInside)
addTarget(self, action: #selector(AGIconButton.userDidTouchUpOutside), for: .touchUpOutside)
}
//only called at design time
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setUpView()
addTarget(self, action: #selector(AGIconButton.userDidTouchDown), for: .touchDown)
addTarget(self, action: #selector(AGIconButton.userDidTouchUp), for: .touchUpInside)
addTarget(self, action: #selector(AGIconButton.userDidTouchUpOutside), for: .touchUpOutside)
}
#IBInspectable var iconImage: UIImage = UIImage() {
didSet {
iconImageView.image = iconImage
}
}
#IBInspectable var imageSize: CGFloat = 40 {
didSet {
setUpView()
}
}
#IBInspectable var imagePadding: CGFloat = 10 {
didSet {
setUpView()
}
}
#IBInspectable var iconText: String = "Icon Button Time" {
didSet {
setUpView()
}
}
#IBInspectable var iconTextSize: CGFloat = 15 {
didSet {
setUpView()
}
}
#IBInspectable var iconTextColor: UIColor = UIColor.black {
didSet {
setUpView()
}
}
#IBInspectable var alignment: Int = 1 {
didSet {
setUpView()
}
}
override var intrinsicContentSize: CGSize {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: iconTextSize)
label.text = iconText
label.sizeToFit()
return CGSize(width: imageSize + label.frame.width + imagePadding + (padding * 2), height: CGFloat(max(label.frame.height, imageSize) + padding * 2))
}
#IBInspectable var highLightColor: UIColor = UIColor.lightGray {
didSet {
setUpView()
}
}
#IBInspectable var shouldBounce: Bool = true
#IBInspectable var borderColor: UIColor = UIColor.clear {
didSet {
layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
private func setUpView(){
if iconImageView == nil{
iconImageView = UIImageView(image: iconImage)
iconImageView.contentMode = .scaleAspectFit
iconImageView.isUserInteractionEnabled = false
self.addSubview(iconImageView)
}
if mainSpacer == nil{
mainSpacer = UIView(frame: CGRect(x: 0, y: 0, width: imagePadding, height: self.bounds.height))
mainSpacer.isUserInteractionEnabled = false
self.addSubview(mainSpacer)
}
if iconLabel == nil{
iconLabel = UILabel()
iconLabel.isUserInteractionEnabled = false
self.addSubview(iconLabel)
}
if highlightView == nil{
highlightView = UIView(frame: self.bounds)
highlightView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
highlightView.alpha = 0
highlightView.isUserInteractionEnabled = false
self.addSubview(highlightView)
self.bringSubview(toFront: highlightView)
}
highlightView.backgroundColor = highLightColor
iconLabel.font = UIFont.systemFont(ofSize: iconTextSize)
iconLabel.text = iconText
iconLabel.textColor = iconTextColor
iconLabel.sizeToFit()
var usedWidth : CGFloat = self.intrinsicContentSize.width
if bounds.width < usedWidth{
usedWidth = bounds.width
}
let maxImageHeight = min(self.bounds.height - padding, imageSize)
//resize iconlabel if we have to
if maxImageHeight + imagePadding + iconLabel.bounds.width + padding * 2 > usedWidth{
iconLabel.frame = CGRect(x: 0, y: 0, width: self.bounds.width - iconImageView.bounds.width - imagePadding - padding * 2, height: iconLabel.bounds.height)
iconLabel.fitFontForSize(minFontSize: 1, maxFontSize: iconTextSize, accuracy: 1.0)
}
let maxWidth = (self.bounds.width - iconLabel.bounds.width - maxImageHeight - imagePadding) / 2
switch alignment {
case 0:
//intrinsic left
iconImageView.frame = CGRect(x:padding, y: self.bounds.midY - maxImageHeight/2,width:maxImageHeight, height: maxImageHeight)
mainSpacer.frame = CGRect(x: maxImageHeight + padding, y: 0, width: imagePadding, height: self.bounds.height)
iconLabel.frame = CGRect(x: maxImageHeight + imagePadding + padding, y: 0, width: iconLabel.frame.width, height: bounds.height)
break
case 1:
//intrinsic center
iconImageView.frame = CGRect(x: maxWidth, y: self.bounds.midY - maxImageHeight/2,width:maxImageHeight, height: maxImageHeight)
mainSpacer.frame = CGRect(x: maxWidth + maxImageHeight, y: 0, width: imagePadding, height: self.bounds.height)
iconLabel.frame = CGRect(x: maxWidth + maxImageHeight + imagePadding, y: 0, width: iconLabel.frame.width, height: self.bounds.height)
break
case 2:
//intrinsic icon right text aligned right
iconLabel.frame = CGRect(x: maxWidth, y: 0, width: iconLabel.frame.width, height: self.bounds.height)
iconLabel.textAlignment = .right
mainSpacer.frame = CGRect(x: iconLabel.frame.width + maxWidth, y: 0, width: imagePadding, height: self.bounds.height)
iconImageView.frame = CGRect(x: iconLabel.frame.width + imagePadding + maxWidth, y: self.bounds.midY - maxImageHeight/2,width:maxImageHeight, height: maxImageHeight)
break
case 3:
//intrinsic center invert icon
iconLabel.frame = CGRect(x:maxWidth, y: 0, width: iconLabel.frame.width, height: self.bounds.height)
mainSpacer.frame = CGRect(x: maxWidth + iconLabel.bounds.width, y: 0, width: imagePadding, height: self.bounds.height)
iconImageView.frame = CGRect(x: maxWidth + iconLabel.bounds.width + imagePadding, y: self.bounds.midY - maxImageHeight/2,width:maxImageHeight, height: maxImageHeight)
break
default:
//intrinsic center
iconImageView.frame = CGRect(x: maxWidth, y: self.bounds.midY - maxImageHeight/2,width:maxImageHeight, height: maxImageHeight)
mainSpacer.frame = CGRect(x: maxWidth + maxImageHeight, y: 0, width: imagePadding, height: self.bounds.height)
iconLabel.frame = CGRect(x: maxWidth + maxImageHeight + imagePadding, y: 0, width: iconLabel.frame.width, height: self.bounds.height)
}
}
//layout subviews
override func layoutSubviews() {
super.layoutSubviews()
setUpView()
}
//MARK: Touch Events
//TODO: run on timer to simulate a real press
func userDidTouchDown(){
if shouldBounce == true{
animateBouncyDown()
}else{
self.animateHighlightTo(alpha: 0.3)
}
}
func userDidTouchUp(){
if shouldBounce == true{
animateBouncyUp()
}else{
self.animateHighlightTo(alpha: 0)
}
}
func userDidTouchUpOutside(){
if shouldBounce == true{
animateBouncyUp()
}else{
self.animateHighlightTo(alpha: 0)
}
}
func animateHighlightTo(alpha:CGFloat){
UIView.animate(withDuration: 0.2, animations: { [weak self] in
self?.highlightView.alpha = alpha
})
}
func animateBouncyDown(){
self.transform = CGAffineTransform.identity
UIView.animate(withDuration: 0.15, animations: { [weak self] in
self?.transform = CGAffineTransform(scaleX: 0.85, y: 0.85)
})
}
func animateBouncyUp(){
UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.8, options: .curveEaseInOut, animations: {[weak self] in
if self != nil{
self?.transform = CGAffineTransform.identity
}
}, completion: nil)
}
}
extension UILabel {
func fitFontForSize( minFontSize : CGFloat = 1.0, maxFontSize : CGFloat = 300.0, accuracy : CGFloat = 1.0) {
var maxFontSize = maxFontSize
var minFontSize = minFontSize
assert(maxFontSize > minFontSize)
layoutIfNeeded() // Can be removed at your own discretion
let constrainedSize = bounds.size
while maxFontSize - minFontSize > accuracy {
let midFontSize : CGFloat = ((minFontSize + maxFontSize) / 2)
font = font.withSize(midFontSize)
sizeToFit()
let checkSize : CGSize = bounds.size
if checkSize.height < constrainedSize.height && checkSize.width < constrainedSize.width {
minFontSize = midFontSize
} else {
maxFontSize = midFontSize
}
}
font = font.withSize(minFontSize)
sizeToFit()
layoutIfNeeded()
}
}
There doesn't seem to be any way to do this. If you drop a custom control into another xib and add subviews to the custom control in Interface Builder, those subviews appear at the same level as the custom control in the view hierarchy when you load the xib. It looks like custom controls can not act as containers in other xibs.

Custom progress view

I want to do a custom progress view for my iOS app, with 2 dots. Here is my code:
import UIKit
#IBDesignable
class StepProgressView: UIView {
#IBInspectable var progress: Float = 0
var progressColor = UIColor.blackColor()
var bgColor = UIColor.whiteColor()
override func layoutSubviews() {
self.backgroundColor = UIColor.clearColor()
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
let height = frame.height-8
let circle1 = UIView(frame: CGRect(x: frame.width*(1/3), y: 0, width: frame.height, height: frame.height))
circle1.backgroundColor = bgColor
circle1.layer.cornerRadius = frame.height/2
addSubview(circle1)
let circle2 = UIView(frame: CGRect(x: frame.width*(2/3), y: 0, width: frame.height, height: frame.height))
circle2.backgroundColor = bgColor
circle2.layer.cornerRadius = frame.height/2
addSubview(circle2)
let bgView = UIView(frame: CGRect(x: height/2, y: 4, width: frame.width-height/2, height: height))
bgView.backgroundColor = bgColor
bgView.layer.cornerRadius = height/2
addSubview(bgView)
let progressView = UIView(frame: CGRect(x: 0, y: 4, width: frame.width*CGFloat(progress), height: height))
progressView.backgroundColor = progressColor
progressView.layer.cornerRadius = height/2
addSubview(progressView)
}
}
The result:
However, as you can see, the circles aren't "filled" when the progression pass over one of them, and I don't know how to do that. I could create another view but I don't know how to handle the corner radius.
Can you help me ?
Thanks

Resources