使用CoreGraphics发布绘图自定义UIView

时间:2014-07-17 16:54:02

标签: ios uiview swift core-graphics

我正在尝试使用CoreGraphics进行自定义垂直切换。我在单独的视图中切换背景和切换拇指绘图,但出于某种原因,我似乎无法将拇指视图的背景颜色设置为clearcolor。任何帮助将不胜感激!

enter image description here

![import UIKit
import QuartzCore

class ThumbView:UIView {

    var thumbPath = UIBezierPath()
    init(frame: CGRect) {
        super.init(frame: frame)
       // self.opaque = false
      //  self.backgroundColor = UIColor.clearColor()
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
        self.opaque = false
        self.backgroundColor = UIColor.clearColor()
    }

    override func drawRect(rect: CGRect) {
        let contentFrame = rect
        let context = UIGraphicsGetCurrentContext()

        let bgPath = UIBezierPath(rect: self.frame)
        let bgColor = UIColor.clearColor()
        bgColor.setFill()
        bgPath.fill()

        self.backgroundColor = bgColor;

        let white = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
        let shadowOffset = CGSizeMake(0.1, 3.1)
        let shadowBlurRadius: CGFloat = 5
        let shadow = UIColor.darkGrayColor()

        CGContextSaveGState(context)
        //// thumb Drawing
        thumbPath = UIBezierPath(ovalInRect: CGRectMake(0, 0, rect.size.height, rect.size.width))
        CGContextSaveGState(context)
        CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor)
        white.setFill()
        thumbPath.fill()
        CGContextRestoreGState(context)
    }
}

class VerticalSwitch: UIView {

    var switchBackgroundPath = UIBezierPath()
    var thumbView = ThumbView()

    init(frame: CGRect) {
        super.init(frame: frame)
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
        self.clipsToBounds = true
        thumbView = ThumbView()
        NSLog("%@", NSStringFromCGRect(self.frame))
        self.addSubview(thumbView)
    }

    override func layoutSubviews() {
        thumbView.frame = CGRectMake(5, 5, self.frame.size.width - 10, self.frame.size.width - 10)
    }

    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect)
    {
        let contentFrame = rect
        //// General Declarations
        let context = UIGraphicsGetCurrentContext()

        //// Color Declarations
        let gDGreen = UIColor(red: 0.157, green: 0.475, blue: 0.153, alpha: 1.000)

        //// Shadow Declarations
        let innerShadow = UIColor.darkGrayColor().colorWithAlphaComponent(0.9)
        let innerShadowOffset = CGSizeMake(0.1, -5.1)
        let innerShadowBlurRadius: CGFloat = 10

        //// switchBackground Drawing
        switchBackgroundPath.moveToPoint(CGPointMake(contentFrame.minX + 85.36, contentFrame.minY + 0.06764 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.23095 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 95.12, contentFrame.minY + 0.11274 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.17184 * contentFrame.height))
        switchBackgroundPath.addLineToPoint(CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.76905 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 85.36, contentFrame.minY + 0.93236 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.82816 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 95.12, contentFrame.minY + 0.88726 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 14.64, contentFrame.minY + 0.93236 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 65.83, contentFrame.minY + 1.02255 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 34.17, contentFrame.minY + 1.02255 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX, contentFrame.minY + 0.76905 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 4.88, contentFrame.minY + 0.88726 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX, contentFrame.minY + 0.82816 * contentFrame.height))
        switchBackgroundPath.addLineToPoint(CGPointMake(contentFrame.minX, contentFrame.minY + 0.23095 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 14.64, contentFrame.minY + 0.06764 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX, contentFrame.minY + 0.17184 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 4.88, contentFrame.minY + 0.11274 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 85.36, contentFrame.minY + 0.06764 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 34.17, contentFrame.minY + -0.02255 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 65.83, contentFrame.minY + -0.02255 * contentFrame.height))
        switchBackgroundPath.closePath()
        gDGreen.setFill()
        switchBackgroundPath.fill()

        ////// switchBackground Inner Shadow
        CGContextSaveGState(context)
        CGContextClipToRect(context, switchBackgroundPath.bounds)
        CGContextSetShadow(context, CGSizeMake(0, 0), 0)
        CGContextSetAlpha(context, CGColorGetAlpha(innerShadow.CGColor))
        CGContextBeginTransparencyLayer(context, nil)
        let switchBackgroundOpaqueShadow = innerShadow.colorWithAlphaComponent(1)
        CGContextSetShadowWithColor(context, innerShadowOffset, innerShadowBlurRadius, switchBackgroundOpaqueShadow.CGColor)
        CGContextSetBlendMode(context, kCGBlendModeSourceOut)
        CGContextBeginTransparencyLayer(context, nil)

        switchBackgroundOpaqueShadow.setFill()
        switchBackgroundPath.fill()

        CGContextEndTransparencyLayer(context)
        CGContextRestoreGState(context)
    }

    override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {

    }
}]

1 个答案:

答案 0 :(得分:4)

您应该使用带有frame参数的构造函数创建thumbView:

thumbView = ThumbView(frame: CGRectMake(0,0, 0, 0))

ThumbView init(frame: CGRect)应为:

init(frame: CGRect) {
    super.init(frame: frame)
    self.opaque = false
    self.backgroundColor = UIColor.clearColor()
}

或者,您可以在ThumbView中创建无参数构造,但必须调用super.init(frame:CGRectMake(0,0, 0, 0))并设置opaque和background属性。

<强>更新

  • 您也忘了在ThumbView CGContextRestoreGState方法中调用drawRect:。应该在方法的最后添加。
  • 忘记在VerticalSwitch CGContextEndTransparencyLayer方法中致电drawRect:。应该在另一个CGContextEndTransparencyLayer方法调用之后添加。

模拟器截图:

Final Screenshot

所有代码(包含修正):

import Foundation
import UIKit
import QuartzCore

class ThumbView:UIView {

    var thumbPath = UIBezierPath()
    init(frame: CGRect) {
        super.init(frame: frame)
         self.opaque = false
          self.backgroundColor = UIColor.clearColor()
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
        self.opaque = false
        self.backgroundColor = UIColor.clearColor()
    }

    override func drawRect(rect: CGRect) {
        let contentFrame = rect
        let context = UIGraphicsGetCurrentContext()

        let bgPath = UIBezierPath(rect: self.frame)
        let bgColor = UIColor.clearColor()
        bgColor.setFill()
        bgPath.fill()

        self.backgroundColor = bgColor;

        let white = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
        let shadowOffset = CGSizeMake(0.1, 3.1)
        let shadowBlurRadius: CGFloat = 5
        let shadow = UIColor.darkGrayColor()

        CGContextSaveGState(context)
        //// thumb Drawing
        thumbPath = UIBezierPath(ovalInRect: CGRectMake(0, 0, rect.size.height, rect.size.width))
        CGContextSaveGState(context)
        CGContextSetShadowWithColor(context, shadowOffset, shadowBlurRadius, shadow.CGColor)
        white.setFill()
        thumbPath.fill()
        CGContextRestoreGState(context)
        CGContextRestoreGState(context)
    }
}

class VerticalSwitch: UIView {

    var switchBackgroundPath = UIBezierPath()
    var thumbView = ThumbView()

    init(frame: CGRect) {
        super.init(frame: frame)
    }

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
        self.clipsToBounds = true
        thumbView = ThumbView(frame: CGRectMake(0,0, 0, 0))
        NSLog("%@", NSStringFromCGRect(self.frame))
        self.addSubview(thumbView)
    }

    override func layoutSubviews() {
        thumbView.frame = CGRectMake(5, 5, self.frame.size.width - 10, self.frame.size.width - 10)
    }

    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect)
    {
        let contentFrame = rect
        //// General Declarations
        let context = UIGraphicsGetCurrentContext()

        //// Color Declarations
        let gDGreen = UIColor(red: 0.157, green: 0.475, blue: 0.153, alpha: 1.000)

        //// Shadow Declarations
        let innerShadow = UIColor.darkGrayColor().colorWithAlphaComponent(0.9)
        let innerShadowOffset = CGSizeMake(0.1, -5.1)
        let innerShadowBlurRadius: CGFloat = 10

        //// switchBackground Drawing
        switchBackgroundPath.moveToPoint(CGPointMake(contentFrame.minX + 85.36, contentFrame.minY + 0.06764 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.23095 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 95.12, contentFrame.minY + 0.11274 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.17184 * contentFrame.height))
        switchBackgroundPath.addLineToPoint(CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.76905 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 85.36, contentFrame.minY + 0.93236 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 100, contentFrame.minY + 0.82816 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 95.12, contentFrame.minY + 0.88726 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 14.64, contentFrame.minY + 0.93236 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 65.83, contentFrame.minY + 1.02255 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 34.17, contentFrame.minY + 1.02255 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX, contentFrame.minY + 0.76905 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 4.88, contentFrame.minY + 0.88726 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX, contentFrame.minY + 0.82816 * contentFrame.height))
        switchBackgroundPath.addLineToPoint(CGPointMake(contentFrame.minX, contentFrame.minY + 0.23095 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 14.64, contentFrame.minY + 0.06764 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX, contentFrame.minY + 0.17184 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 4.88, contentFrame.minY + 0.11274 * contentFrame.height))
        switchBackgroundPath.addCurveToPoint(CGPointMake(contentFrame.minX + 85.36, contentFrame.minY + 0.06764 * contentFrame.height), controlPoint1: CGPointMake(contentFrame.minX + 34.17, contentFrame.minY + -0.02255 * contentFrame.height), controlPoint2: CGPointMake(contentFrame.minX + 65.83, contentFrame.minY + -0.02255 * contentFrame.height))
        switchBackgroundPath.closePath()
        gDGreen.setFill()
        switchBackgroundPath.fill()

        ////// switchBackground Inner Shadow
        CGContextSaveGState(context)
        CGContextClipToRect(context, switchBackgroundPath.bounds)
        CGContextSetShadow(context, CGSizeMake(0, 0), 0)
        CGContextSetAlpha(context, CGColorGetAlpha(innerShadow.CGColor))
        CGContextBeginTransparencyLayer(context, nil)
        let switchBackgroundOpaqueShadow = innerShadow.colorWithAlphaComponent(1)
        CGContextSetShadowWithColor(context, innerShadowOffset, innerShadowBlurRadius, switchBackgroundOpaqueShadow.CGColor)
        CGContextSetBlendMode(context, kCGBlendModeSourceOut)
        CGContextBeginTransparencyLayer(context, nil)

        switchBackgroundOpaqueShadow.setFill()
        switchBackgroundPath.fill()

        CGContextEndTransparencyLayer(context)
        CGContextEndTransparencyLayer(context)
        CGContextRestoreGState(context)
    }

    override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {

    }
}