skip to Main Content

enter image description here

I’m working on an ios project & I want to add a circular text label along with circular wheel using Swift language.The wheel can also rotate, and the labels with curved text will rotate to 360 degrees. I’m looking for any third party or any supporting file so that I can simulate the same behaviour.. Thanks in advance

I want to integrate the above functionality with swift language

For more reference please check the attached image:

2

Answers


  1. class CircularWheelView: UIView {
        
        private let imageLayer = CALayer()
        
        var image: UIImage? {
            didSet {
                setNeedsLayout()
            }
        }
        
        var labelTexts: [String] = [""] {
               didSet {
                   drawTextLabels()
               }
           }
        override func layoutSubviews() {
            super.layoutSubviews()
            
            // Update the image layer when the image changes or the view's bounds change
            if let image = image {
                let imageSize = CGSize(width: bounds.width / 2, height: bounds.height / 2)
                imageLayer.frame = CGRect(x: (bounds.width - imageSize.width) / 2, y: (bounds.height - imageSize.height) / 2, width: imageSize.width, height: imageSize.height)
                imageLayer.contents = image.cgImage
            }
        }
        
        override func draw(_ rect: CGRect) {
            // Draw the circular ring
            let ringPath = UIBezierPath(ovalIn: bounds.insetBy(dx: 20, dy: 20))
            UIColor.lightGray.setStroke()
            ringPath.lineWidth = 40
            ringPath.stroke()
            
            // Draw the text labels along the circumference
            drawTextLabels()
        }
        
        private func drawTextLabels() {
            let center = CGPoint(x: bounds.midX, y: bounds.midY)
            let radius = min(bounds.width, bounds.height) / 2.3
            let labelCount = labelTexts.count // Number of text labels
            let labelAngle = CGFloat.pi * 2.0 / CGFloat(labelCount)
            
            for i in 0..<labelCount {
                let label = UILabel()
                label.text = labelTexts[i]
                label.sizeToFit()
                
                // Calculate label position
                let angle = CGFloat(i) * labelAngle
                let x = center.x + radius * cos(angle)
                let y = center.y + radius * sin(angle)
                
                // Adjust label position to make it circular
                label.center = CGPoint(x: x, y: y)
                label.transform = CGAffineTransform(rotationAngle: angle + CGFloat.pi / 2)
                
                addSubview(label)
            }
        }
        
    
    
        func rotateWheel() {
            let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
            rotationAnimation.fromValue = 0.0
            rotationAnimation.toValue = CGFloat.pi * 2.0
            rotationAnimation.duration = 2.0
            rotationAnimation.repeatCount = .infinity
            layer.add(rotationAnimation, forKey: "rotate")
        }
    }
    

    USAGE

    let circularWheelView = CircularWheelView(frame: CGRect(x: 50, y: 100, width: 300, height: 300))
            circularWheelView.labelTexts = ["Settings 1", "Setting 2", "Setting 3", "Setting 4", "Setting 5"]
            circularWheelView.image = UIImage(resource: .letter)
            circularWheelView.backgroundColor = .clear
            view.addSubview(circularWheelView)
            
            // Start rotating the wheel
            circularWheelView.rotateWheel()
    

    Please check video for reference

    Login or Signup to reply.
  2. The answer to SwiftUI: How to have equal spacing between letters in a curved text view? provides a SwiftUI solution for showing curved text (it was my answer).

    Here is how it could be used to show curved labels like in your image:

    struct ContentView: View {
    
        private let textRadius: CGFloat = 130
        @State private var rotationDegrees = 0.0
    
        private func curvedText(text: String, angleDegrees: Double) -> some View {
    
            // See https://stackoverflow.com/a/77280669/20386264
            CurvedText(string: text, radius: textRadius)
                .offset(y: -textRadius)
                .rotationEffect(.degrees(angleDegrees))
        }
    
        var body: some View {
            ZStack {
                Circle()
                    .stroke(.white, lineWidth: 35)
                    .frame(width: textRadius * 2, height: textRadius * 2)
    
                curvedText(text: "Krisje >", angleDegrees: 0)
                curvedText(text: "Settings >", angleDegrees: 90)
                curvedText(text: "Statistieken >", angleDegrees: 180)
                curvedText(text: "Stijn >", angleDegrees: 270)
            }
            .font(.custom("MarkerFelt-Thin", size: 24))
            .foregroundStyle(.black)
            .rotationEffect(.degrees(rotationDegrees))
            .animation(
                .linear(duration: 20).repeatForever(autoreverses: false),
                value: rotationDegrees
            )
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color(red: 0.53, green: 0.58, blue: 0.63))
            .onAppear { rotationDegrees = 360 }
        }
    }
    

    Animation

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search