Created
January 22, 2021 14:25
-
-
Save Coder-ACJHP/f3ca7cc4bdcfed876fd223c4aa7df205 to your computer and use it in GitHub Desktop.
This function is let you draw text around circle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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