Как создать пользовательский UILabel с ключевым текстом [duplicate]

Некоторые статистические данные, связанные с этим известным вопросом с двойной точностью.

При добавлении всех значений ( a + b ) с шагом 0,1 (от 0,1 до 100) имеем ~ 15% вероятность ошибки точности. Обратите внимание, что ошибка может привести к несколько большим или меньшим значениям. Вот несколько примеров:

0.1 + 0.2 = 0.30000000000000004 (BIGGER)
0.1 + 0.7 = 0.7999999999999999 (SMALLER)
...
1.7 + 1.9 = 3.5999999999999996 (SMALLER)
1.7 + 2.2 = 3.9000000000000004 (BIGGER)
...
3.2 + 3.6 = 6.800000000000001 (BIGGER)
3.2 + 4.4 = 7.6000000000000005 (BIGGER)

При вычитании всех значений ( a - b , где a> b ) с шагом 0,1 (от 100 до 0,1), мы имеем вероятность 34% точности. Вот несколько примеров:

0.6 - 0.2 = 0.39999999999999997 (SMALLER)
0.5 - 0.4 = 0.09999999999999998 (SMALLER)
...
2.1 - 0.2 = 1.9000000000000001 (BIGGER)
2.0 - 1.9 = 0.10000000000000009 (BIGGER)
...
100 - 99.9 = 0.09999999999999432 (SMALLER)
100 - 99.8 = 0.20000000000000284 (BIGGER)

* 15% и 34% действительно огромны, поэтому всегда используйте BigDecimal, когда точность имеет большое значение. С 2 десятичными цифрами (шаг 0,01) ситуация несколько ухудшается (18% и 36%).

0
задан Joe Huang 11 February 2016 в 10:14
поделиться

4 ответа

После того, как мой код решил мой вопрос:

override func drawRect(rect: CGRect) {
    super.drawRect(rect)

    let  context  = UIGraphicsGetCurrentContext()

    // Flip the coordinate system
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    let path = CGPathCreateMutable()
    CGPathAddRect(path, nil, self.bounds)

    let str = NSMutableAttributedString(string: "some text goes here...")

    // set font color
    str.addAttribute(kCTForegroundColorAttributeName as String, value:UIColor.blackColor() , range: NSMakeRange(0,str.length))
    // set font name & size
    let fontRef = UIFont.systemFontOfSize(20, weight: UIFontWeightMedium)
    str.addAttribute(kCTFontAttributeName as String, value: fontRef, range:NSMakeRange(0, str.length))

    let frameSetter = CTFramesetterCreateWithAttributedString(str)
    let ctFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,str.length), path, nil)

    CTFrameDraw(ctFrame, context!)
}
1
ответ дан Joe Huang 25 August 2018 в 14:35
поделиться

Обновление для Swift 4.0:

override func draw(_ rect: CGRect) {
     super.draw(rect)

    // context allows you to manipulate the drawing context (i'm setup to draw or bail out)
    guard let context: CGContext = UIGraphicsGetCurrentContext() else {
        return
    }

    // Flip the coordinate system
    context.textMatrix = CGAffineTransform.identity;
    context.translateBy(x: 0, y: self.bounds.size.height);
    context.scaleBy(x: 1.0, y: -1.0);

    let path = CGMutablePath()
    path.addRect(self.bounds)

    let str = NSMutableAttributedString(string: "00:00:00")

    // set font color
    str.addAttribute(NSAttributedStringKey(rawValue: kCTForegroundColorAttributeName as String), value:UIColor.purple , range: NSMakeRange(0,str.length))
    // set font name & size
    let fontRef = UIFont.systemFont(ofSize: 20, weight: UIFont.Weight.bold)
    str.addAttribute(NSAttributedStringKey(rawValue: kCTFontAttributeName as String), value: fontRef, range:NSMakeRange(0, str.length))

    let frameSetter = CTFramesetterCreateWithAttributedString(str)
    let ctFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,str.length), path, nil)

    CTFrameDraw(ctFrame, context)       
}
1
ответ дан Miss Kensington 25 August 2018 в 14:35
поделиться

Обновлено для swift 3.0:

if let context  = UIGraphicsGetCurrentContext(){

            // Flip the coordinate system
            context.textMatrix = CGAffineTransform.identity;
            context.translateBy(x: 0, y: self.bounds.size.height);
            context.scaleBy(x: 1.0, y: -1.0);

            let path = CGMutablePath()
            path.addRect(self.bounds)

            let str = NSMutableAttributedString(string: "some text goes here...")

            // set font color
            str.addAttribute(kCTForegroundColorAttributeName as String, value:UIColor.black , range: NSMakeRange(0,str.length))
            // set font name & size
            let fontRef = UIFont.systemFont(ofSize: 20, weight: UIFontWeightMedium)
            str.addAttribute(kCTFontAttributeName as String, value: fontRef, range:NSMakeRange(0, str.length))

            let frameSetter = CTFramesetterCreateWithAttributedString(str)
            let ctFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,str.length), path, nil)

            CTFrameDraw(ctFrame, context)
        }
0
ответ дан parbo 25 August 2018 в 14:35
поделиться

Попробуйте следующее:

func drawText(context: CGContextRef, text: NSString, attributes: [String: AnyObject], x: CGFloat, y: CGFloat) -> CGSize {
    let font = attributes[NSFontAttributeName] as UIFont
    let attributedString = NSAttributedString(string: text, attributes: attributes)

    let textSize = text.sizeWithAttributes(attributes)

    // y: Add font.descender (its a negative value) to align the text at the baseline
    let textPath    = CGPathCreateWithRect(CGRect(x: x, y: y + font.descender, width: ceil(textSize.width), height: ceil(textSize.height)), nil)
    let frameSetter = CTFramesetterCreateWithAttributedString(attributedString)
    let frame       = CTFramesetterCreateFrame(frameSetter, CFRange(location: 0, length: attributedString.length), textPath, nil)

    CTFrameDraw(frame, context)

    return textSize
    }

И назовите это:

var textAttributes: [String: AnyObject] = [
    NSForegroundColorAttributeName : UIColor(white: 1.0, alpha: 1.0).CGColor,
    NSFontAttributeName : UIFont.systemFontOfSize(17)
]

drawText(ctx, text: "Hello, World!", attributes: textAttributes, x: 50, y: 50)

Надеюсь, что это сработает!

0
ответ дан TechBee 25 August 2018 в 14:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: