I am trying to display a fraction as something like 1/2 but I want to line to be horizontal so the fraction looks more fraction like, some thing like this:
1
_
2
However with no massive space and in a way that I can use it inside one UILabel (which can have multiple lines). I also need to be able to put a fraction as the numerator/denominator of a fraction and so on. Any suggestions? (Fonts, characters...)
Thank you, Gleb Koval
Here's a UIView
subclass that draws a fraction:
class FractionView: UIView {
var font: UIFont = UIFont.systemFont(ofSize: 16) {
didSet { self.setNeedsDisplay() }
}
var numerator: Int = 1 {
didSet { self.setNeedsDisplay() }
}
var denominator: Int = 2{
didSet { self.setNeedsDisplay() }
}
var spacing: CGFloat = 5{
didSet { self.setNeedsDisplay() }
}
override func draw(_ rect: CGRect) {
let numString = "\(numerator)" as NSString
let numWidth = numString.size(withAttributes: [.font: font]).width
let denomString = "\(denominator)" as NSString
let denomWidth = denomString.size(withAttributes: [.font: font]).width
let numX: CGFloat
let denomX: CGFloat
if numWidth <= denomWidth {
denomX = 0
numX = (denomWidth - numWidth) / 2
} else {
denomX = (numWidth - denomWidth) / 2
numX = 0
}
numString.draw(at: CGPoint(x: numX, y: 0), withAttributes: [.font : font])
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: font.lineHeight + spacing))
path.addLine(to: CGPoint(x: self.frame.maxX, y: font.lineHeight + spacing))
UIColor.black.setStroke()
path.lineWidth = 1
path.stroke()
denomString.draw(at: CGPoint(x: denomX, y: font.lineHeight + spacing * 2), withAttributes: [.font: font])
}
}
// usage:
let width = ("12" as NSString).size(withAttributes: [.font: UIFont.systemFont(ofSize: 16)]).width
let view = FractionView(frame: CGRect(x: 0, y: 0, width: width, height: 48))
view.backgroundColor = .white
view.denominator = 12
As Sulthan in comments has suggested, using an NSAttributedString
would be an easier approach:
let attrString = NSMutableAttributedString(string: "1", attributes: [NSAttributedStringKey.underlineStyle : 1])
attrString.append(NSAttributedString(string: "\n2"))
attrString
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
label.attributedText = attrString
label.numberOfLines = 2