user4806509
user4806509

Reputation: 3011

How to correct UIView and UILabel text scaling with pixelation?

When I add a UILabel with text to a UIView and then scale the UIView, the contents is displayed with pixelation. The greater the scale factor, the greater the pixelation.

I understand using a CATextLayer might be able to assist and could display the scaled UIView and UILabel text without pixelation but I don't know how to implement it.

This is how I create a triangle and scale it with no pixelation. It scales with perfect sharp edges.

How can I ensure the same when scaling a UILabel ?

func drawTriangle() {
    let path = UIBezierPath()
    path.moveToPoint(CGPoint(x: 0, y: 100))
    path.addLineToPoint(CGPoint(x: 100, y: 100))
    path.addLineToPoint(CGPoint(x: 50, y: 0))
    path.closePath()

    let shape = CAShapeLayer()
    shape.path = path.CGPath
    shape.fillColor = UIColor.blackColor().CGColor

    viewTriangle.layer.insertSublayer(shape, atIndex: 0)
}

func scaleTriangle() {
    viewTriangle.transform = CGAffineTransformMakeScale(5, 5)
}

Question:

In Swift code, how do I convert the below to use a CATextLayer so that it scales with no pixelation?


Problem code:

func drawLetter() { // pixelated when scaled ?
    let labelLetter = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    labelLetter.text = "A"
    labelLetter.backgroundColor = UIColor.clearColor()
    labelLetter.textColor = UIColor.blackColor()
    labelLetter.font = UIFont(name: labelLetter.font.fontName, size: 144)
    labelLetter.textAlignment = .Center
    viewLetter.addSubview(labelLetter)
    }
}

func scaleView() {
    let scaleValue: CGFloat = 5
    self.viewLetter.transform = CGAffineTransformMakeScale(scaleValue, scaleValue)
}

Image:

enter image description here

Upvotes: 6

Views: 1356

Answers (3)

user4806509
user4806509

Reputation: 3011

Instead of CGAffineTransformMakeScale(_:_:) try‭ using CGAffineTransform(scaleX:y:).‬

Before

    func scaleView() {
        let scaleValue: CGFloat = 5
        self.viewLetter.transform = CGAffineTransformMakeScale(scaleValue, scaleValue)
    }

After

    func scaleView() {
        let scaleValue: CGFloat = 5
        self.viewLetter.transform = CGAffineTransform(scaleX: scaleValue, y: scaleValue)
    }

Upvotes: 0

Mars
Mars

Reputation: 2572

This scales up the view 5x and sets the content's scale as well

func scaleView() {
    let scaleValue: CGFloat = 5
    self.viewLetter.transform = CGAffineTransformMakeScale(scaleValue, scaleValue)
    self.labelLetter.contentScaleFactor = scaleValue * x //scaleValue * native content scale  (2 on iPhone 8 and 3 on iPhone 8 plus)
}

Upvotes: 1

matt
matt

Reputation: 535889

I understand using a CATextLayer uses paths for drawing and will display the scaled UIView and UILabel text without pixelation.

You understand wrong. A CATextLayer draws text and scales its text. This is an either-or thing: use CATextLayer or a UILabel.

It's easy to get more detail in a scaled view: that is what a view's contentScaleFactor is for. Simply increase it, taking into account the existing scale due to the resolution of the screen, to match your scale transform.

Upvotes: 0

Related Questions