Swift 3 draw uiimage programmatically

时间:2017-07-10 15:24:19

标签: ios swift core-graphics

I don't have experience in Core Graphics but I need to draw a dynamic uiimage that look like these:

left

whole

(Actually I want the grey area to be clear. So the red color will look like floating)

This is the code I tried:

public extension UIImage {

    public convenience init?(color: UIColor, size: CGSize = CGSize(width: 27, height: 5), isWhole: Bool = true) {
        let totalHeight: CGFloat = 5.0
        let topRectHeight: CGFloat = 1.0

        //if (isWhole) {
        let topRect = CGRect(origin: .zero, size: CGSize(width: size.width, height: topRectHeight))
        UIGraphicsBeginImageContextWithOptions(topRect.size, false, 0.0)
        color.setFill()
        UIRectFill(topRect)

        let bottomRect = CGRect(origin: CGPoint(x: 0, y: topRectHeight), size: CGSize(width: size.width, height: totalHeight - topRectHeight))
        UIGraphicsBeginImageContextWithOptions(bottomRect.size, false, 0.0)
        UIColor.blue.setFill()
        UIRectFill(bottomRect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        guard let cgImage = image?.cgImage else { return nil }
        self.init(cgImage: cgImage)
    }

3 个答案:

答案 0 :(得分:1)

如果将isWhole属性设置为false,则可以拥有第一个图像,如果将其设置为true,则可以获得第二个图像。您可以在viewDidLoad中粘贴此代码以进行测试和播放。

    var isWhole = false
    UIGraphicsBeginImageContextWithOptions(CGSize.init(width: 27, height: 5), false,0.0)
    var context = UIGraphicsGetCurrentContext()
    context?.setFillColor(UIColor.red.cgColor)
    if(context != nil){
        if(isWhole){
            context?.fill(CGRect(x: 0, y: 0, width: 27, height: 2.5))
        }
        else{
            context?.fill(CGRect(x: 0, y: 0, width: 13.5, height: 2.5))
        }
        context?.setFillColor(UIColor.gray.cgColor)
        context?.fill(CGRect(x: 0, y: 2.5, width: 27, height: 2.5))
    }


    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    var imageView = UIImageView(frame: CGRect(x: 100, y: 200, width: 27, height: 5))
    imageView.image = newImage
    self.view.addSubview(imageView)
    UIGraphicsEndImageContext()

如果你需要你的红色矩形与圆角,只需改变填充(rect:CGRect),路径如下:

    if(isWhole){
        context?.addPath(CGPath(roundedRect: CGRect(x: 0, y: 0, width: 27, height: 2.5), cornerWidth: 1, cornerHeight: 1, transform: nil))
        context?.fillPath()
    }

答案 1 :(得分:0)

我建议在你创建的第一个上下文中创建两个路径,即

let topPath = UIBezierPath(rect: topRect)
color.setFill()
topPath.fill()

let bottomPath = UIBezierPath(rect: bottomRect)
UIColor.blue.setFill()
bottomPath.fill()

然后你可以从当前的上下文中获取图像。

答案 2 :(得分:0)

我知道你在评论中说过你不能使用UIViews,但你想要的是什么"看起来"通过视图轻松完成。为什么不 ,然后将其变成UIImage

override func viewDidLoad() {
    super.viewDidLoad()

    let imageContainer = UIView(frame: CGRect(x: 30, y: 40, width: 110, height: 60))
    imageContainer.backgroundColor = view.backgroundColor
    view.addSubview(imageContainer)

    let redView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
    redView.backgroundColor = UIColor.red
    let grayView = UIView(frame: CGRect(x: 10, y: 30, width: 100, height: 30))
    grayView.backgroundColor = UIColor.gray
    imageContainer.addSubview(redView)
    imageContainer.addSubview(grayView)

    let imageView = UIImageView(frame: CGRect(x: 100, y: 140, width: 200, height: 200))
    imageView.contentMode = .scaleAspectFit
    imageView.image = createImage(imageContainer)

    view.addSubview(imageView)
}

func createImage(_ view: UIView) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(
        CGSize(width: view.frame.width, height: view.frame.height), true, 1)
    view.layer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image!
}