我是iOS开发人员,使用swift4。
我制作了圆形标签,但我希望将UILabel的每个文字都折成圆圈。
我知道在SpriteKit中,可以使用SKWarpGeometryGrid进行Warp转换。
由于我不打算制作游戏,我想要扭曲UILabel,这是UIView的子类,没有Sprite Kit。
你能告诉我如何只用UIKit弯曲UILabel或UIView吗?
import UIKit
//func centreArcPerpendicular() {
// guard let context = UIGraphicsGetCurrentContext() else { return }
// let string = text ?? ""
// let size = bounds.size
// context.translateBy(x: size.width / 2, y: size.height / 2)
//
// let radius = getRadiusForLabel()
// let count = string.count
// let attributes: [NSAttributedStringKey: Any] =
// [
// .font: self.font!,
// .kern: space
// ]
//
//
// let characters: [String] = string.map { String($0) }
// var arcs: [CGFloat] = []
// var totalArc: CGFloat = 0
//
// for i in 0 ..< count {
// arcs += [chordToArc(characters[i].size(withAttributes: attributes).width, radius: radius)]
// totalArc += arcs[i]
// }
//
// let direction: CGFloat = clockwise ? -1 : 1
// let slantCorrection = clockwise ? -CGFloat.pi / 2 : CGFloat.pi / 2
//
// var thetaI = _angle - direction * totalArc / 2
//
// for (i, arc) in arcs.enumerated() {
// thetaI += direction * arc / 2
// center(text: characters[i], context: context, radius: radius, angle: thetaI, slantAngle: thetaI + slantCorrection)
// thetaI += direction * arc / 2
// }
//}
class CircularLabel: UILabel {
@IBInspectable var angle: CGFloat = 1.6
@IBInspectable var DegMode: Bool = false
@IBInspectable var clockwise: Bool = true
@IBInspectable var radius:CGFloat=16
@IBInspectable var space: CGFloat = 0
private var _angle: CGFloat {
return DegMode ? (angle * CGFloat.pi / 180.0) : angle
}
override func draw(_ rect: CGRect) {
centerText()
}
func centerText() {
guard let context = UIGraphicsGetCurrentContext() else { return }
let string = text ?? ""
let size = bounds.size
context.translateBy(x: size.width / 2, y: size.height / 2)
let direction: CGFloat = clockwise ? -1 : 1
let slantCorrection = clockwise ? -CGFloat.pi / 2 : CGFloat.pi / 2
var thetaI = _angle
string
.map { String($0) }
.forEach {
center(text: $0, context: context, radius: radius, angle: thetaI, slantAngle: thetaI + slantCorrection)
thetaI += direction*CGFloat.pi * 2 / CGFloat(string.count)
}
}
func chordToArc(_ chord: CGFloat, radius: CGFloat) -> CGFloat {
return 2 * asin(chord / (2 * radius))
}
func center(text str: String, context: CGContext, radius r: CGFloat, angle theta: CGFloat, slantAngle: CGFloat) {
let attributes: [NSAttributedStringKey: Any] = [
.foregroundColor: textColor!,
.font: font!
]
context.saveGState()
context.translateBy(x: r * cos(theta), y: -(r * sin(theta)))
context.rotate(by: -slantAngle)
// print(CIFilter.filterNames(inCategory: kCICategoryDistortionEffect))
let offset = str.size(withAttributes: attributes)
context.translateBy(x: -offset.width / 2, y: -offset.height / 2)
let label=UILabel()
label.attributedText=NSAttributedString(string: str, attributes: attributes)
label.drawText(in: CGRect(origin: CGPoint.zero, size: str.size(withAttributes: attributes)))
context.restoreGState()
}
func getRadiusForLabel() -> CGFloat {
let smallestWidthOrHeight = min(bounds.size.height, bounds.size.width)
let heightOfFont = text?.size(withAttributes: [NSAttributedStringKey.font: self.font]).height ?? 0
return (smallestWidthOrHeight / 2) - heightOfFont + 5
}
}