Графические точки не работают за пределами viewDidLoad - PullRequest
0 голосов
/ 14 мая 2019

Я создал графический класс, чтобы показать пользователю, какие графические точки выбираются в соответствии с информацией о пользователе.

Если я использую объект 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 (баллы: [100, 400, 200, 250])

введите описание изображения здесь

Кто-нибудь?

Код для 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 голосов
/ 15 мая 2019

Мне удалось исправить (кажется временным исправлением) создание новой переменной Int в верхней части проекта и передачу данных выборки из БД в эти переменные.Таким образом, я могу использовать их в viewDidLoad вместо функции извлечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...