Mickey Mouse
Mickey Mouse

Reputation: 1771

Swift - Adding text to a resizable image

I've been fiddling around with different techniques on how to implement a resizable image in the Asset Catalog, but there are no examples out there on how to add text to these resizable images in Swift (even in Apple's own guides) and allow them to resize dynamically.

If any knows how to do that, knows links to blogs which explain that, that will be helpful.

Upvotes: 3

Views: 1466

Answers (1)

clearlight
clearlight

Reputation: 12615

UIImage class scales an image to the dimensions you set it at via constraints or frame depending on how you're laying your stuff out. You can load an image from the assets catalog via the name, as you know.

So just upload the images to the asset catalog in all resolutions for the device classes (e.g. 1x, 2x, 3x...) and then create a UIImage() and set the frame of the UIImage instance after it is a subview, and there you go. iOS will select the right image size based on the device/screen you have and that's about as well as you can do to get a good resolution for a scaled image.

By default, you'll be using constraints to size the UIImage in Interface Builder. If you create the image programmatically you'll have more flexibility but more work as to how you size the UIImage after you place it in a superview.

The following is some code to scale a UIImage. Once you have a bitmap context of the image as shown in the function below, you can use other drawing and font functions with the derived context handle to add text. As you search core image and core text classes you'll notice conversion options and ways manipulate and add text and do all kinds of image manipulation.

func scaleImage(image: UIImage, newSize: CGSize) -> UIImage {
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
    var colorSpace = CGColorSpaceCreateDeviceRGB()
    var bytesPerRow = CGImageGetBytesPerRow(image.CGImage)
    var ctx = CGBitmapContextCreate(nil,
                     UInt(newSize.width),
                     UInt(newSize.height),
                     CGImageGetBitsPerComponent(image.CGImage),
                     UInt(newSize.width * 4),
                     colorSpace,
                     bitmapInfo)!
    CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh)
    CGContextDrawImage(ctx, CGRect(origin: CGPointZero, size: CGSizeMake(newSize.width, newSize.height)), image.CGImage)
    return UIImage(CGImage: CGBitmapContextCreateImage(ctx))!
}

You could also convert the label to an image by programmatically taking a snapshot as shown here:

    func takeSnapshot(view: UIView) -> UIImageView {
        var image : UIImage
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0)
        view.layer.renderInContext(UIGraphicsGetCurrentContext())
        image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();
        var imageView = UIImageView(image: image)
        imageView.opaque = false
        return imageView
    }

And overlay one image on the other like this:

func overlayImages(images: [UIImage]) -> UIImage? {
    var compositeImage : UIImage?
     if images.count > 0 {
        var maxWidth = CGFloat(0), maxHeight = CGFloat(0)
        for image in images {
            if image.size.width > maxWidth {
                maxWidth = image.size.width
            }
            if image.size.height > maxHeight {
                maxHeight = image.size.height
            }
        }
        var size = CGSizeMake(maxWidth, maxHeight)
        UIGraphicsBeginImageContext(size);
        for image in images {
            var x = maxWidth / 2 - image.size.width / 2
            var y = maxHeight / 2 - image.size.height / 2
            image.drawInRect(CGRectMake(x, y, image.size.width, image.size.height))
        }
        compositeImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return compositeImage;

}

You could also subclass your UIImageView() and override drawRect() method rect to add some text as shown, but don't forget to call super() to make sure the image is drawn as well.

var stringAttrs = [UITextAttributeFont : font,      
                  UITextAttributeTextColor : textColor ]

var attrStr = NSAttributedString(string:"hello", attributes:stringAttrs)
attrStr.drawAtPoint:CGPointMake(10.f, 10.f)

Upvotes: 5

Related Questions