ShinobiChart inside UICollectionView



I want to add a shinobiChart to cell of the UICollectionView. But when I run the app I have this error:   “thread1 : EXC_BAD_ACCESS”.

But if I run only the shinobiChart without UICollectionView this works.

I was missing some thing?


// chartTest.swift

import UIKit

class ChartTest: UIViewController, SChartDatasource {
    override func viewDidLoad() {
        var chart = ShinobiChart(frame: CGRectMake(0, 0, 370, 200));
        chart.datasource = self;
     // chart.gesturePanType = SChartGesturePanTypeNone;
    /* SChartDatasource methods */
    func numberOfSeriesInSChart(chart: ShinobiChart!) -> Int {
        return 1
    func sChart(chart: ShinobiChart!, seriesAtIndex index: Int) -> SChartSeries! {
        return SChartLineSeries()
    func sChart(chart: ShinobiChart!, numberOfDataPointsForSeriesAtIndex seriesIndex: Int) -> Int {
        return 100
    func sChart(chart: ShinobiChart!, dataPointAtIndex dataIndex: Int, forSeriesAtIndex seriesIndex: Int) -> SChartData! {
        let dp = SChartDataPoint()
        dp.xValue = dataIndex
        dp.yValue = dataIndex * dataIndex
        return dp
    override func didReceiveMemoryWarning() {
        // Dispose of any resources that can be recreated.


// ViewControllerCollection.swift

import UIKit

public class ViewControllerUICollectionSection: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource{ 
    public var layoutCollectionView : UICollectionView!

    var apiController : APIController?;
    public var sections : [Row]?;
    var screenID : String!;
    var isTest : Bool! = false;
    public init(id:String, isTest: Bool){
        self.screenID = id;
        self.isTest = isTest;
        super.init(nibName: nil, bundle: nil);
        let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        apiController = appDelegate.getAPIController();

    required public init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder);

    override public func viewDidLoad() {
        self.sections = [Row]();
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        layout.minimumLineSpacing = 0;
        layoutCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        layoutCollectionView.dataSource = self
        layoutCollectionView.delegate = self
        layoutCollectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
        layoutCollectionView.backgroundColor = UIColor.whiteColor()

    override public func didReceiveMemoryWarning() {
        // Dispose of any resources that can be recreated.
    func getLayout(){
        if isTest == false{
            apiController!.getLayout(self.screenID) { (resultsArr: NSDictionary) in
                self.sections! = LayoutParser.layoutWithJson(resultsArr);

    public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return sections!.count;
     public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return sections![section].panels.count;
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewFlowLayout,
        sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
            var widthx = sections![indexPath.section].panels[indexPath.row].width;
            var heightx = sections![indexPath.section].panels[indexPath.row].height;
            return CGSize(width: CGFloat(widthx), height: CGFloat(heightx))
    public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as UICollectionViewCell
        var panelId : String = sections![indexPath.section].panels[indexPath.row];
        var widgetType = sections![indexPath.section].panels[indexPath.row].widget.type;
        var widget : Widget = sections![indexPath.section].panels[indexPath.row].widget;
        cell.layer.borderWidth = 2;
        cell.layer.borderColor = UIColor.blackColor().CGColor;
        cell.addSubview(ChartTest().view);//WidgetVCFactory.createWidgetVC(widgetType, widget: widget)!);
        return cell



Hi ateresa,

I’ve not had the time to look through your code, but here are some suggestions that will hopefully be useful:

  • The crash happening only when you use a chart in a collection view, but not when you use the chart in isolation makes it sound like there may be an issue with how collection view is being configured.
  • Use the backtrace from the crash to debug where the issue is occuring. Once you know where the crash is occuring in the code you’ll probably have a better idea of how to fix it. 
  • If that fails then try launching your app with some breakpoints in and stepping through to find out where the crash occurs.

I hope that helps! Let us know how you get on! :slight_smile:




I choosed this solution:

  1. Keep a reference to the view controllers whose views you wish to display in the cells of the collection view.

The following code is a simple view controller that demonstrates this, using your ChartTest view controller. Notice for simplicity that it subclasses UICollectionViewController and that the sizing parameters etc have been set up in a storyboard:

public class ViewController : UICollectionViewController {

let cellVCs = [ChartTest(), ChartTest(), ChartTest()]

public override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {

return 1


public override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

return 3


public override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(“Cell”, forIndexPath: indexPath) as UICollectionViewCell

cell.layer.borderWidth = 2;

cell.layer.borderColor = UIColor.blackColor().CGColor;


return cell



Note that the view controllers are retained in the cellVCs array property.


Thanks for sharing that. I’m glad you managed to find an acceptable solution!