想要使用协议构建带有代理和数据源的Bargraph

时间:2016-10-19 12:28:48

标签: ios swift xcode

我正在尝试构建一个条形图视图,为该图形视图创建委托和数据源。为图表创建委托和数据源的协议。

protocol BarGraphDatasource{
    func grapgView(grapgView:BarGraph, numberOfItemsInGraph items:Int)->Int
    func grapgView(grapgView: BarGraph, didSelectItemAtIndex index: Int)
}

// Bargraph View类如下所示

class BarGraph: UIScrollView {


    var  delegte: BarGraphDatasource! = nil{

        didSet{
            self.reloadGraph()
        }
    }

     var barWidth : CGFloat = 24 {

        didSet{
                self.reloadGraph()
        }
    }
    var minimumSpacing : CGFloat = 10 {

        didSet{
            self.reloadGraph()
        }
    }

    var numberOfItems : Int = 0 {
        didSet{
            self.reloadGraph()
        }
    }
     var barColor : UIColor = UIColor.lightGrayColor() {

        didSet{
            self.reloadGraph()
        }
    }



    init() {
        super.init(frame: CGRectZero)
        self.reloadGraph()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }
    func reloadGraph(){
        self.setContentSizeForGraph()
    }

    func setContentSizeForGraph() {

        if self.numberOfItems > 0 {
            self.contentSize = CGSizeMake((self.barWidth * CGFloat(self.numberOfItems) + self.minimumSpacing), self.frame.height);
            var xValue:CGFloat = 0
            for i in 1...self.numberOfItems {
                xValue = xValue + CGFloat(CGFloat(i) + self.minimumSpacing)
                print("xValue: \(xValue)")
                let frame = CGRectMake(xValue, 0, self.barWidth, 50)
                let barView = UIView(frame: frame)
                barView.backgroundColor = self.barColor
                self.addSubview(barView)
            }
        }
    }
}

//这是我的ViewController类

class ViewController: UIViewController,BarGraphDatasource {

    @IBOutlet weak var grapView :  BarGraph?

    var arrayItems: NSArray = []

    override func viewDidLoad() {
        super.viewDidLoad()

        arrayItems = [1,2,3,4,5]
        grapView?.barWidth = 10;
        grapView?.delegte = self;

        grapView?.reloadGraph()
    }


    func grapgView(grapgView: BarGraph, numberOfItemsInGraph items: Int) -> Int {
        return arrayItems.count // how can i pass this value to the graph view from here       ******* 
    }  
    func grapgView(grapgView: BarGraph, didSelectItemAtIndex index: Int) {
        print(arrayItems[index]) // how can i call this method on click of bar view       ******* 
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

//这里我无法获取图形,也无法在ViewController类中调用协议方法

numberOfItemsInGraph 当我们设置此项时,我想将此值传递给图表中的BarGraph

didSelectItemAtIndex 如何将动作提供给所选项目

1 个答案:

答案 0 :(得分:1)

你不需要一直调用reloadGraph()。当你分配委托时,它将被调用。你可以稍后明确地调用它。

第二,你必须从BarGraph类的某个地方调用这些委托方法。我已经更改了一些代码,请试试这个。

    import UIKit

protocol BarGraphDatasource{
    func grapgView(grapgView:BarGraph, numberOfItemsInGraph items:Int)->Int
    func grapgView(grapgView: BarGraph, didSelectItemAtIndex index: Int)
    func grapgView(grapgView: BarGraph, setHeightOfBarAtIndex index: Int)->CGFloat
}
// Bargraph View class is like below

class BarGraph: UIScrollView{


    var  delegte: BarGraphDatasource! = nil{

        didSet{
            self.reloadGraph()
        }
    }

    var barWidth : CGFloat = 24
    var minimumSpacing : CGFloat = 10
    var numberOfItems : Int = 0
    var barColor : UIColor = UIColor.lightGrayColor()
    var barViews : [UIButton] = []


    init() {
        super.init(frame: CGRectZero)
        self.reloadGraph()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }
    func reloadGraph(){
        numberOfItems = delegte!.grapgView(self, numberOfItemsInGraph: numberOfItems)
        self.setContentSizeForGraph()

    }

    func setContentSizeForGraph() {

        if self.numberOfItems > 0 {

            self.contentSize = CGSizeMake((self.barWidth * CGFloat(self.numberOfItems) + self.minimumSpacing), self.frame.height);
            var xValue:CGFloat = 0

            for i in 1...self.numberOfItems {
                xValue = xValue + CGFloat(CGFloat(i) + self.minimumSpacing + self.barWidth)
                print("xValue: \(xValue)")
                let frame = CGRectMake(xValue, self.layer.frame.size.height-delegte.grapgView(self, setHeightOfBarAtIndex: i-1), self.barWidth, delegte.grapgView(self, setHeightOfBarAtIndex: i-1))
                let barView = UIButton(frame: frame)
                barView.backgroundColor = self.barColor
                barViews.append(barView)
                barView.addTarget(self, action: #selector(BarGraph.send_ButtonIndex(_:)), forControlEvents: UIControlEvents.TouchUpInside)
                self.addSubview(barView)
            }
        }
    }

    func send_ButtonIndex(barView : UIButton)
    {

        delegte!.grapgView(self, didSelectItemAtIndex: barViews.indexOf(barView)!)
    }

}

这是带有数据源的BarGraph类。我已经实现了一个额外的委托方法以便更好地使用。 Viewcontroller代码如下。

    import UIKit

class ViewController: UIViewController,BarGraphDatasource {

    @IBOutlet weak var grapView :  BarGraph?

    var arrayItems: NSArray = []
    var heightOfBars: [CGFloat] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        arrayItems = [1,2,3,4,5]
        heightOfBars = [20,30,25,60,40]
        grapView?.barWidth = 20;
        grapView?.barColor = UIColor.brownColor()
        grapView?.minimumSpacing = 15;
        grapView?.delegte = self;
    }


    func grapgView(grapgView: BarGraph, numberOfItemsInGraph items: Int) -> Int {
        return arrayItems.count //pass this value to the graph view from here       *******
    }
    func grapgView(grapgView: BarGraph, didSelectItemAtIndex index: Int) {
        print(arrayItems[index]) //call this method on click of bar view       *******
    }

    func grapgView(grapgView: BarGraph, setHeightOfBarAtIndex index: Int) -> CGFloat
    {
        return heightOfBars[index]
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}