图形点在viewDidLoad之外不起作用

时间:2019-05-14 16:57:39

标签: arrays swift firebase graph

我已经创建了一个图形类,以向用户显示图形点以及相应的用户信息。

如果我使用graphicView对象并在viewDidLoad处添加点,则将正确显示图形,如果不存在,则图形将不显示数据。

请参见下面的图形代码和我要求标记点的代码。

class GraphView: UIView {

private struct Constants {
    static let cornerRadiusSize = CGSize(width: 8.0, height: 8.0)
    static let margin: CGFloat = 40.0
    static let topBorder: CGFloat = 30
    static let bottomBorder: CGFloat = 40
    static let colorAlpha: CGFloat = 0.3
    static let circleDiameter: CGFloat = 5.0
}

//1 - the properties for the gradient
var startColor: UIColor = UIColor.rgb(red: 14, green: 40, blue: 80)
var endColor: UIColor = UIColor.rgb(red: 14, green: 40, blue: 80)

//Weekly sample data
var graphPoints: [Int] = [0]

override func draw(_ rect: CGRect) {

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

    let path = UIBezierPath(roundedRect: rect,
                            byRoundingCorners: UIRectCorner.allCorners,
                            cornerRadii: Constants.cornerRadiusSize)
    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 = CGGradient(colorsSpace: colorSpace,
                              colors: colors as CFArray,
                              locations: colorLocations)!

    //6 - draw the gradient
    var startPoint = CGPoint.zero
    var endPoint = CGPoint(x: 0, y: self.bounds.height)
    context.drawLinearGradient(gradient,
                               start: startPoint,
                               end: endPoint,
                               options: CGGradientDrawingOptions(rawValue: 0))

    //calculate the x point
    let margin = Constants.margin
    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 = Constants.topBorder
    let bottomBorder: CGFloat = Constants.bottomBorder
    let graphHeight = height - topBorder - bottomBorder
    let maxValue = graphPoints.max()!
    let columnYPoint = { (graphPoint:Int) -> CGFloat in
        var y:CGFloat = CGFloat(graphPoint) / CGFloat(maxValue) * graphHeight
        y = graphHeight + topBorder - y // Flip the graph
        return y
    }

    // draw the line graph
    UIColor.white.setFill()
    UIColor.white.setStroke()

    //set up the points line
    let graphPath = UIBezierPath()
    //go to start of line
    graphPath.move(to: 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.addLine(to: nextPoint)
    }

    //Create the clipping path for the graph gradient

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

    //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.addLine(to: CGPoint(x: columnXPoint(graphPoints.count - 1), y:height))
    clippingPath.addLine(to: CGPoint(x:columnXPoint(0), y:height))
    clippingPath.close()

    //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)

    context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: CGGradientDrawingOptions(rawValue: 0))
    context.restoreGState()

    //draw the line on top of the clipped gradient
    graphPath.lineWidth = 3.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 -= Constants.circleDiameter / 2
        point.y -= Constants.circleDiameter / 2

        let circle = UIBezierPath(ovalIn: CGRect(origin: point, size: CGSize(width: Constants.circleDiameter, height: Constants.circleDiameter)))
        circle.fill()
    }

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

    //top line
    linePath.move(to: CGPoint(x:margin, y: topBorder))
    linePath.addLine(to: CGPoint(x: width - margin, y:topBorder))

    //center line
    linePath.move(to: CGPoint(x:margin, y: graphHeight/2 + topBorder))
    linePath.addLine(to: CGPoint(x:width - margin, y:graphHeight/2 + topBorder))

    //bottom line
    linePath.move(to: CGPoint(x:margin, y:height - bottomBorder))
    linePath.addLine(to: CGPoint(x:width - margin, y:height - bottomBorder))
    let color = UIColor(white: 1.0, alpha: Constants.colorAlpha)
    color.setStroke()

    linePath.lineWidth = 1.0
    linePath.stroke()
   }

}

我正在尝试通过用户输入相应地标记点-参见下文:

func budgetAvailableCalculationFunction() {

let bankValue = (userSalary as NSString).integerValue
let bankPorcentage: Int = 100

let expenses = (userExpenses as NSString).integerValue

    let calculation1: Int = expenses * bankPorcentage
    let calculation2: Int = calculation1 / bankValue

    let cashPorcentageAvailable = calculation2

    let value: [Int] = [expenses]

    self.setupGraphy(points: value)

    progressView.progress = 0.0
    progress.completedUnitCount = Int64(cashPorcentageAvailable)
    progressView.setProgress(Float(self.progress.fractionCompleted), animated: true)
    progressView.progressTintColor = UIColor.rgb(red: 239, green: 75, blue: 92)
    progressView.backgroundColor = UIColor.rgb(red: 239, green: 75, blue: 92)
    progressView.trackTintColor = .white
    progressView.clipsToBounds = false
    progressView.translatesAutoresizingMaskIntoConstraints = false
    progressView.layer.cornerRadius = 0
    porcentageLabelForMonth.text = "\(Int(self.progress.fractionCompleted * 100)) %"

}

setupGraphy只是一个函数,它返回用户添加索引的数组。

请注意,在viewDidLoad上使用相同的功能是有效的:

self.setupGraphy(points:[100,400,200,250])

enter image description here

有人吗?

viewDidLoad的代码:

override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = UIColor.rgb(red: 245, green: 246, blue: 250)

    tableView.delegate = self
    tableView.dataSource = self
    tableView.register(LastTransactionsCell.self, forCellReuseIdentifier: "LastTransactionsCell")
    tableView.backgroundColor = .clear

    let now = Date()
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy - LLLL"
    let nameOfMonth = dateFormatter.string(from: now)
    currentMonthLabel.text = nameOfMonth

    setupUIXViews()

    fetchUserInfo()
    //static data for now
    *self.setupGraphy(points: [100, 400, 200, 250])*

    DispatchQueue.main.asyncAfter(deadline: .now() + 2){
        self.budgetAvailableCalculationFunction()
    }
}

1 个答案:

答案 0 :(得分:0)

我设法修复(似乎是临时修复)的方法是在项目顶部创建一个新的Int变量,并将从数据库中获取的数据传递给这些变量。这样,我可以在viewDidLoad而不是fetch函数中使用它们。