如何将参数从一个类传递到UIView类?迅速

时间:2016-04-08 13:17:42

标签: ios swift uiview

我的应用中有一个deep = true类,用于绘制折线图。在那里,我分配我的UIView变量,如下所示:

graphPoints

我想要做的是从另一个类传递一个var graphPoints:[Int] = [1,2,3,5,7,9] var graphPoints2:[Int] = [1,2,3,5,7,9] 数组并分配这些变量,但我不知道该怎么做。最初,我将所有代码放入一个Int func作为参数,并从另一个类调用它,但它完全停止绘制图形。我该怎么做?

以下是我的array [Int] UIVIew班级代码:

GraphPlotter

DBController,func dosmth我传递数组:

import UIKit

@IBDesignable class GraphPlotter: UIView {

var graphPoints:[Int] = [1,2,3,5,7,9]
var graphPoints2:[Int] = [1,2,3,5,7,9]

//1 - the properties for the gradient
var startColor: UIColor = UIColor.redColor()
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.zero
    var endPoint = CGPoint(x:0, y:self.bounds.height)
    CGContextDrawLinearGradient(context,
        gradient,
        startPoint,
        endPoint,
        [])

    //calculate the x point

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

    // calculate the y point

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

    // draw the line graph

    UIColor.flatTealColor().setFill()
    UIColor.flatTealColor().setStroke()

    //set up the points line
    let graphPath = UIBezierPath()
    //go to start of line
    graphPath.moveToPoint(CGPoint(x:columnXPoint(0),
        y:columnYPoint(graphPoints2[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(graphPoints2[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:margin, y: highestYPoint)
    endPoint = CGPoint(x:margin, y:self.bounds.height)

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, [])
    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(graphPoints2[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()
        let label = UILabel(frame: CGRectMake(0, 0, 200, 21))
        label.center = CGPointMake(160, 284)
        label.textAlignment = NSTextAlignment.Center
        //            label.text = "I'am a test label"
        self.addSubview(label)
    }



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

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

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

    //bottom line
    linePath.moveToPoint(CGPoint(x:margin,
        y:height - bottomBorder))
    linePath.addLineToPoint(CGPoint(x:width - margin,
        y:height - bottomBorder))
    let color = UIColor.flatTealColor()
    color.setStroke()

    linePath.lineWidth = 1.0
    linePath.stroke()

}

}

2 个答案:

答案 0 :(得分:0)

因此,您的drawRect方法基于两个变量graphPointsgraphPoints2。创建一个方法,其作用是更新这两个变量的数组,然后调用setNeedsDisplay - 这将继续重绘视图。

    func plotGraphPoints(gpArray1 : [Int], andMorePoints gpArray2: [Int] ) {

        print("Old Values", self.graphPoints)
        self.graphPoints = gpArray1
        self.graphPoints2 = gpArray2
        print("New values", self.graphPoints)

        self.setNeedsDisplay()
    }

答案 1 :(得分:0)

首先,我将其设置为以便任何更新都会重绘视图:

var graphPoints:[Int]? { didSet { setNeedsDisplay() } }
var graphPoints2:[Int]? { didSet { setNeedsDisplay() } }

注意,我制作了这些选项,因为您通常希望它处理缺少nil值而不是虚拟值的数据。但是,这确实假设您要调整实现来检测和处理这些nil值,例如,在开始绘制线条之前,请执行

guard graphPoints != nil && graphPoints2 != nil else { return }

但是,我注意到整个班级都是IBDesignable,在这种情况下,你可能想要一个提供样本数据的prepareForInterfaceBuilder

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()

    graphPoints = [1,2,3,5,7,9]
    graphPoints2 = [1,2,3,5,7,9]
}

其次,您的其他类需要引用此自定义视图。

  • 如果这是&#34;其他&#34; class是视图控制器,您通过IB添加了自定义视图,您只需将自定义视图的@IBOutlet添加到此视图控制器。如果以编程方式添加此自定义视图,则只需在将某个属性添加到视图层次结构后对其进行引用即可。但是,您添加了对该视图的引用,例如graphView,您只需设置这些属性:

    graphView.graphPoints = ...
    graphView.graphPoints2 = ...
    
  • 如果这是&#34;其他&#34; class不是视图控制器(在讨论中,听起来有问题的类是用于处理异步DropBox API的控制器),你还需要给该类一些机制来引用视图控制器(从而定制)视图)。您可以通过实现&#34;完成处理程序模式&#34;来完成此操作。或者#34;委托协议&#34;图案。