exyte / Macaw

Powerful and easy-to-use vector graphics Swift library with SVG support
MIT License
6.01k stars 554 forks source link

Instance member 'variableName' cannot be used on type 'MacawChartView' #660

Closed locagirl closed 4 years ago

locagirl commented 4 years ago

I initialized my variables under init function of subclass MacawChartView : MacawView. But I'm encountering an error "Instance member 'variableName' cannot be used on type 'MacawChartView'"

How do you initialize a MacawChartView with dynamic variables? Is there a way?

amarunko commented 4 years ago

Hi, @locagirl, sorry, didn't catch, can you attach a code example?

locagirl commented 4 years ago

I cannot initialize the userX, userY, userW, and userH variables and I encounter error: Instance member 'userX' cannot be used on type 'MacawChartView'

class MacawViewChart: MacawView {
    var userX : Double = 0
    var userY : Double = 0
    var userW : Double = 0
    var userH : Double = 0

    private static func addItems() -> [Node] {
        let valueRect = Rect(x: userValue, y: userValue, w: userValue, h: userValue).fill(with: Color.blue)
        var newNodes: [Node] = []
        newNodes.append(valueRect)
        return newNodes
    }
   override init(frame: CGRect) {
        super.init(frame: frame)
        node = MacawChartView.createChart()
        backgroundColor = .lightGray
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(node: MacawChartView.createChart(), coder: aDecoder)
        backgroundColor = .clear
    }
    init(frame: CGRect, userX: Double, userY: Double, userW: Double, userH: Double){
        self.userX = userX
        self.userY = userY
        self.userW = userW
        self.userH = userH
    }  
}
amarunko commented 4 years ago

missed super.init(frame: frame) in last init method

locagirl commented 4 years ago

Oops. Sorry my bad I just forget to include it there. But the error still persists even with that line of code.

amarunko commented 4 years ago

Sorry, maybe I missed something, but for me, everything works as expected, for example:

private lazy var chart: MacawViewChart = {
        let chart = MacawViewChart(frame: CGRect.zero, userX: 0, userY: 0, userW: 0, userH: 0)
        chart.userH = 29
        return chart
    }()

Can you attach the example of code where exactly you are using these variables and getting an error

locagirl commented 4 years ago

import Foundation
import Macaw

class MacawChartView: MacawView {
    var maxValue : Int = 0
    var lineWidth : Double = 0

    var maxLines : Int = 0
    var lineInterval : Int = 0

    var lineSpacing: Double = 0
    var yAxisHeight: Double = 0

    var maxPermitted : Double = 0
    var minPermitted : Double = 0
    var heightPermitted : Double = 0
    var widthPermitted : Double = 0

    var userAverage :  Double = 0
    var userValue : Double = 0

    override init(frame: CGRect) {
        super.init(frame: frame)
        node = MacawChartView.createChart()
        backgroundColor = .lightGray
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(node: MacawChartView.createChart(), coder: aDecoder)
        backgroundColor = .clear
    }

    init(frame: CGRect, maxValue: Int, maxLines: Int, maxPermitted: Double, minPermitted: Double,userAverage : Double, userValue : Double) {
        super.init(frame: frame)
        self.maxValue = maxValue
        self.lineWidth =  300

        self.maxLines = maxLines
        self.lineInterval = Int(self.maxValue/self.maxLines)

        self.lineSpacing = 30
        self.yAxisHeight = (Double(self.maxLines) * self.lineSpacing) + 25

        self.maxPermitted = maxPermitted //UserInput where in Y axis
        self.minPermitted = minPermitted //userInput where in Y axis
        self.heightPermitted = (self.minPermitted - self.maxPermitted) * self.lineSpacing
        self.widthPermitted = self.lineWidth / 2

        self.userAverage = userAverage //UserInput
        self.userValue = userValue //UserInput

        node = MacawChartView.createChart()
        backgroundColor = .lightGray
    }

    private static func createChart() -> Group {
        let items: [Node] = addYAxisItems() + addItems() + addLightItems()
        return Group(contents: items, place: .identity)
    }

    private static func addYAxisItems() -> [Node] {
        var newNodes: [Node] = []

        for i in 1...maxLines{
            let y = (Double(i) * lineSpacing)

            let valueLine = Line(x1: 55, y1: y, x2: 50+lineWidth, y2: y).stroke(fill: Color.black.with(a: 0.10))
            let valueText = Text(text: "\(i * lineInterval)", align: .max, baseline: .mid, place: .move(dx: 50, dy: y))
            valueText.fill = Color.black

            newNodes.append(valueLine)
            newNodes.append(valueText)
        }

        let yAxis = Line(x1: 55, y1: 0, x2: 55, y2: yAxisHeight).stroke(fill: Color.black.with(a: 0.25))
        newNodes.append(yAxis)

        return newNodes
    }

    private static func addItems() -> [Node] {
        let valueRect = Rect(x: widthPermitted-50, y: maxPermitted*lineSpacing, w: widthPermitted, h: heightPermitted).fill(with: Color.rgba(r: 211, g: 211, b: 211, a: 1))
        let valueXLine = Line(x1: widthPermitted+10, y1: userAverage * lineSpacing, x2: widthPermitted + 40, y2: userAverage * lineSpacing).stroke(fill: Color.blue.with(a: 1))
        let valueYLine = Line(x1: widthPermitted+25, y1: maxPermitted*lineSpacing-15, x2: widthPermitted + 25, y2: heightPermitted*2.5).stroke(fill: Color.black.with(a: 0.50))
        let valueCircle = Circle(cx: widthPermitted+25, cy: userValue*lineSpacing, r: 5).fill(with: RadialGradient(
            stops: [
                Stop(offset: 0, color: Color(val: 0xF5027C)),
                Stop(offset: 1, color: Color(val: 0x850143))
            ]
        ))
        var newNodes: [Node] = []
        newNodes.append(valueYLine)
        newNodes.append(valueRect)
        newNodes.append(valueXLine)
        newNodes.append(valueCircle)
        return newNodes
    }

    private static func addLightItems() -> [Node] {
        let valueRect = Rect(x: lineWidth-22.5, y: yAxisHeight-265, w: 25, h: 80).fill(with: Color.rgba(r: 211, g: 211, b: 211, a: 1))
        var valueCircGreen = Circle(cx: lineWidth-10, cy: yAxisHeight-250, r: 10).stroke(fill: Color.gray)
        var valueCircYellow = Circle(cx: lineWidth-10, cy: yAxisHeight-225, r: 10).stroke(fill: Color.gray)
        var valueCircRed = Circle(cx: lineWidth-10, cy: yAxisHeight-200, r: 10).stroke(fill: Color.gray)

        if userValue == userAverage {
            valueCircGreen = Circle(cx: lineWidth-10, cy: yAxisHeight-250, r: 10).fill(with: Color.green)
            valueCircYellow = Circle(cx: lineWidth-10, cy: yAxisHeight-225, r: 10).stroke(fill: Color.gray)
            valueCircRed = Circle(cx: lineWidth-10, cy: yAxisHeight-200, r: 10).stroke(fill: Color.gray)
        }else if userValue < maxPermitted || userValue > minPermitted {
            valueCircGreen = Circle(cx: lineWidth-10, cy: yAxisHeight-250, r: 10).stroke(fill: Color.gray)
            valueCircYellow = Circle(cx: lineWidth-10, cy: yAxisHeight-225, r: 10).stroke(fill: Color.gray)
            valueCircRed = Circle(cx: lineWidth-10, cy: yAxisHeight-200, r: 10).fill(with: Color.red)
        }else{
            valueCircGreen = Circle(cx: lineWidth-10, cy: yAxisHeight-250, r: 10).stroke(fill: Color.gray)
            valueCircYellow = Circle(cx: lineWidth-10, cy: yAxisHeight-225, r: 10).fill(with: Color.yellow)
            valueCircRed = 

Circle(cx: lineWidth-10, cy: yAxisHeight-200, r: 10).stroke(fill: Color.gray)
        }

        var newNodes: [Node] = []
        newNodes.append(valueRect)
        newNodes.append(valueCircGreen)
        newNodes.append(valueCircYellow)
        newNodes.append(valueCircRed)
        return newNodes
    }
}```

This is my entire MacawChartView.class, I am encountering errors on several lines.
<img width="1377" alt="Screen Shot 2020-01-20 at 9 13 58 am" src="https://user-images.githubusercontent.com/48347047/72692244-b2757800-3b65-11ea-9056-31593c1a3dc0.png">
amarunko commented 4 years ago

So, now it's clear, you are using static methods, in static methods you can't use instance variables, in swift you can use object/instance variables only in the instance of this class. Firstly you should initialize an instance in this case, or you can declare needed variables as class/static variables.

ystrot commented 4 years ago

Closing this issue. Please reopen it if you have more questions.