尝试将数据传递给UIViews时EXC_BAD_INSTRUCTION

时间:2015-08-07 21:44:02

标签: ios swift uiview

我创建了一个UIView的调用,我在其中绘制了一个图形。我正在尝试传递新数据并将其更新。

当我在模拟器上运行应用程序并单击视图所在的控制器所在的选项卡时,我收到此错误:

线程1:EXC_BAD_INSTRUCTION(代码= EXC_1386_INVOP,子代码= 0x0)

在这一行:

let maxValue = graphPoints.maxElement()

以下是我的视图代码:

@IBDesignable class GraphView: UIView {

var graphPoints :[Int]!

override init(frame: CGRect) {
    super.init(frame: frame)
}
init(graphPoints: [Int]) {
    self.graphPoints = graphPoints
    super.init(frame: CGRectZero)

}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

@IBInspectable var startColor: UIColor = UIColor.redColor()
@IBInspectable var endColor: UIColor = UIColor.greenColor()

override func drawRect(rect: CGRect) {

    let width = rect.width
    let height = rect.height

    //set up background clipping area
    let path = UIBezierPath(roundedRect: rect,
        byRoundingCorners: UIRectCorner.AllCorners,
        cornerRadii: CGSize(width: 8.0, height: 8.0))
    path.addClip()

    //2 - get the current context
    let context = UIGraphicsGetCurrentContext()
    let colors = [startColor.CGColor, endColor.CGColor]

    //3 - set up the color space
    let colorSpace = CGColorSpaceCreateDeviceRGB()

    //4 - set up the color stops
    let colorLocations:[CGFloat] = [0.0, 1.0]

    //5 - create the gradient
    let gradient = CGGradientCreateWithColors(colorSpace,
        colors,
        colorLocations)

    //6 - draw the gradient
    var startPoint = CGPoint.zeroPoint
    var endPoint = CGPoint(x:0, y:self.bounds.height)
    CGContextDrawLinearGradient(context,
        gradient,
        startPoint,
        endPoint,
        .DrawsBeforeStartLocation)

    //calculate the x point

    let rightMargin:CGFloat = 40
    let leftMargin : CGFloat = 10
    let columnXPoint = { (column:Int) -> CGFloat in
        //Calculate gap between points
        let spacer = (width - rightMargin - leftMargin - 4) /
            CGFloat((self.graphPoints.count - 1))
        var x:CGFloat = CGFloat(column) * spacer
        x += leftMargin + 2
        print(x)
        return x
    }

    // calculate the y point

    let topBorder:CGFloat = 30
    let bottomBorder:CGFloat = 50
    let graphHeight = height - topBorder - bottomBorder
    let maxValue = graphPoints.maxElement()
    let columnYPoint = { (graphPoint:Int) -> CGFloat in
        var y:CGFloat = CGFloat(graphPoint) /
            CGFloat(maxValue!) * graphHeight
        y = graphHeight + topBorder - y // Flip the graph
        print(y)
        return y
    }

    // draw the line graph

    UIColor.whiteColor().setFill()
    UIColor.whiteColor().setStroke()

    //set up the points line
    let graphPath = UIBezierPath()
    //go to start of line
    graphPath.moveToPoint(CGPoint(x:columnXPoint(0), y:columnYPoint(graphPoints[0])))

    //add points for each item in the graphPoints array
    //at the correct (x, y) for the point
    for i in 1..<graphPoints.count {
        let nextPoint = CGPoint(x:columnXPoint(i),
            y:columnYPoint(graphPoints[i]))
        graphPath.addLineToPoint(nextPoint)
    }

    //Create the clipping path for the graph gradient

    //1 - save the state of the context (commented out for now)
    CGContextSaveGState(context)

    //2 - make a copy of the path
    let clippingPath = graphPath.copy() as! UIBezierPath

    //3 - add lines to the copied path to complete the clip area
    clippingPath.addLineToPoint(CGPoint(
        x: columnXPoint(graphPoints.count - 1),
        y:height))
    clippingPath.addLineToPoint(CGPoint(
        x:columnXPoint(0),
        y:height))
    clippingPath.closePath()

    //4 - add the clipping path to the context
    clippingPath.addClip()

    let highestYPoint = columnYPoint(maxValue!)
    startPoint = CGPoint(x:leftMargin, y: highestYPoint)
    endPoint = CGPoint(x:rightMargin, y:self.bounds.height)

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, .DrawsBeforeStartLocation)
    CGContextRestoreGState(context)

    //draw the line on top of the clipped gradient
    graphPath.lineWidth = 2.0
    graphPath.stroke()

    //Draw the circles on top of graph stroke
    for i in 0..<graphPoints.count {
        var point = CGPoint(x:columnXPoint(i), y:columnYPoint(graphPoints[i]))
        point.x -= 5.0/2
        point.y -= 5.0/2

        let circle = UIBezierPath(ovalInRect:
            CGRect(origin: point,
                size: CGSize(width: 5.0, height: 5.0)))
        circle.fill()
    }



    //Draw horizontal graph lines on the top of everything
    let linePath = UIBezierPath()

    //top line
    linePath.moveToPoint(CGPoint(x:leftMargin, y: topBorder))
    linePath.addLineToPoint(CGPoint(x: width - rightMargin,
        y:topBorder))

    //center line
    linePath.moveToPoint(CGPoint(x:leftMargin,
        y: graphHeight/2 + topBorder))
    linePath.addLineToPoint(CGPoint(x:width - rightMargin,
        y:graphHeight/2 + topBorder))

    //bottom line
    linePath.moveToPoint(CGPoint(x:leftMargin,
        y:height - bottomBorder))
    linePath.addLineToPoint(CGPoint(x:width - rightMargin,
        y:height - bottomBorder))
    let color = UIColor(white: 1.0, alpha: 0.3)
    color.setStroke()

    linePath.lineWidth = 1.0
    linePath.stroke()


}

这是我的视图控制器的代码,我将数据传递给视图。

import UIKit
import QuartzCore

class ProgressViewController: UIViewController {


@IBOutlet weak var graphView: UIView! 

var firstGraph : GraphView!


override func viewDidLoad() {

self.graphView = self.firstGraph


self.firstGraph = GraphView(graphPoints: [2240, 1983, 2171, 2017, 1842, 1992, 2347])

我是Swift的新手,在寻找答案之后,我对这个问题感到难过。任何帮助表示赞赏。

0 个答案:

没有答案