Skip to content

Instantly share code, notes, and snippets.

@Coder-ACJHP
Created January 22, 2021 14:25
Show Gist options
  • Save Coder-ACJHP/f3ca7cc4bdcfed876fd223c4aa7df205 to your computer and use it in GitHub Desktop.
Save Coder-ACJHP/f3ca7cc4bdcfed876fd223c4aa7df205 to your computer and use it in GitHub Desktop.
This function is let you draw text around circle.
/// This function drawing text around circle path and its percentage depends on 'bendFactor'
/// - Parameters:
/// - text: String for drawing
/// - bend: value of circle percentage it should be between -2.0 and 2.0
/// - size: Your container view size that you want to draw on it
/// - clockWise: Text should start from where clockWise or anticlockwise
private func drawCurved(text: String, bendFactor bend: CGFloat, fitToSize size: CGSize, clockWise: Bool = true) {
var tempTextRef: String = text
if text.count > maximumCharacterLimit {
let overageCharCount = text.count - Int(maximumCharacterLimit)
tempTextRef = String(text.dropLast(overageCharCount))
}
/// Create a function that calculate maximum font size for single line text depended on given size
func calculateSingleLineFontSizeFitToWidth(frame: CGRect, text: String) -> CGFloat {
let width = frame.size.width
var largestFontSize: CGFloat = 100
while NSString(string: text).size(withAttributes: [NSAttributedString.Key.font: textFXmodel.font.withSize(largestFontSize)]).width > width {
largestFontSize -= 0.5
}
return largestFontSize
}
textFXmodel.text = tempTextRef
let fontSize: CGFloat = calculateSingleLineFontSizeFitToWidth(frame: CGRect(origin: .zero, size: size), text: tempTextRef)
let font = textFXmodel.font
textFXmodel.font = font.withSize(fontSize)
/// Sample fucntion to create attributesDictionary
let attrs: [NSAttributedString.Key : Any] = createAttributesDictionary()
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()!
let centerPoint = CGPoint(x: size.width / 2, y: size.height / 2)
/// We can move center of context with multiplying center.x bend factor / 2
let r = centerPoint.x * 0.75
context.translateBy(x: centerPoint.x, y: centerPoint.y)
context.rotate(by: clockWise ? -.pi / 2 : .pi / 2)
let string: NSString = NSString(string: textFXmodel.text)
var fullSize: CGFloat = 0
/// Get required full size of text size
for index in 0 ..< string.length {
let letter: NSString = string.substring(with: NSRange(location: index, length: 1)) as NSString
let letterSize = letter.size(withAttributes: attrs)
fullSize += letterSize.width
}
var consumedSize: CGFloat = 0
for index in 0 ..< string.length {
let letter: NSString = string.substring(with: NSRange(location: index, length: 1)) as NSString
let letterSize = letter.size(withAttributes: attrs)
/// Move the pointer forward, calculating the
/// new percentage of travel along the path
consumedSize += letterSize.width / 2
let percent = consumedSize / fullSize
let theta = percent * bend * .pi
consumedSize += letterSize.width / 2
/// Encapsulate each stage of the drawing
context.saveGState()
/// Rotate the context
context.rotate(by: theta)
/// Translate up to the edge of the radius and move left by
/// half the letter width. The height translation is negative
/// as this drawing sequence uses the UIKit coordinate system.
/// Transformations that move up go to lower y values.
context.translateBy(x: -letterSize.width / 2, y: -r)
letter.draw(at: .zero, withAttributes: attrs)
context.restoreGState()
}
guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }
imageView.image = image
UIGraphicsEndImageContext()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment