#ios #swift #xcode
#iOS #swift #xcode
Вопрос:
Я пытаюсь создать одно представление гистограммы, чтобы создать делегат и источник данных для этого представления графика. Создание протокола для делегирования и источника данных для графика.
protocol BarGraphDatasource{
func grapgView(grapgView:BarGraph, numberOfItemsInGraph items:Int)->Int
func grapgView(grapgView: BarGraph, didSelectItemAtIndex index: Int)
}
// Класс просмотра гистограммы выглядит следующим образом
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 когда мы устанавливаем это, я хочу передать это значение в гистограмму на графике
didSelectItemAtIndex как назначить действие выбранному элементу
Комментарии:
1. Вы говорите: «как я могу передать это значение в представление графика». Разве это не то, что
return
делает? Поскольку это метод делегирования, я бы ожидал, что он будет вызван из объекта, который ссылается на делегата.
Ответ №1:
Вам не нужно постоянно вызывать reloadGraph(). Когда вы назначаете делегирование, оно будет вызвано. И вы можете вызвать это явно позже.
2-й вы должны вызвать эти методы делегирования откуда-нибудь из класса 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)!)
}
}
Это класс гистограммы с источником данных. Я реализовал один дополнительный метод делегирования для лучшего использования. И код 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.
}
}
Комментарии:
1. Я использовал ваш код в своем проекте, но все еще не могу сгенерировать график. Вот ссылка на мое демонстрационное приложение dropbox.com/s/0eb8fri3miyqr45/HeaderContainer.zip?dl=0
2. @pretam Спасибо
3. var delegte: BarGraphDatasource! = nil{ didSet{ self.reloadGraph() } }
4. значение делегата равно нулю
5. Вы устанавливаете его из ViewController.swift. Тогда это не будет nill