Robbie N

Q: Controling a Gallery With Javascript

I would like to use a Boolean array to control the images in a gallery.  Each index in the array would correlate to a specific image, which would not appear in the gallery if array[i] == false, but the image would appear if array[i] == true.

 

I could use some help with controlling the gallery.  Is there a way to do the following?

    Access a specific slide at an index via javascript.

 

    Get the number of slides in the gallery via javascript.

 

    Add/remove slides to/from the gallery via javascript.

 

    Set the image path for a given slide via javascript.

 

It seemed to me like such information should be here:

https://developer.apple.com/library/iad/documentation/iAdJS/Reference/iAP.Galler yViewClassRef/iAP/iAP.html#//apple_ref/doc/uid/TP40010655

However, I think I must be missing something.  If anyone could point me in the right direction, I would appretiate it!

 

Thanks,

Robbie

Posted on Feb 13, 2014 2:22 PM

Close

Q: Controling a Gallery With Javascript

  • All replies
  • Helpful answers

  • by markmalone,Solvedanswer

    markmalone markmalone Feb 15, 2014 10:19 AM in response to Robbie N
    Level 2 (210 points)
    Feb 15, 2014 10:19 AM in response to Robbie N

    Hey Robbie,

     

    You'll see at the top of that doc a mention that the Gallery View (and all the other multi-cell objects) implement the Cell Container protocol.  Check out the details on the protocol and post back any question you may have - I think you'll find it pretty straight forward. 

     

    There was also as WWDC '13 session that demoed the standard Cover Flow object (also implements Cell Container protocol) using dynamic content fetched from a JSON feed.

     

    Cheers,

     

    -Mark

  • by KPWatts,

    KPWatts KPWatts May 13, 2014 5:18 PM in response to markmalone
    Level 1 (0 points)
    May 13, 2014 5:18 PM in response to markmalone

    Hey Mark,

    I had no idea you were the mark behind the videos !

    I am trying to do exactly what you did in the video with the JSON feed to populate the gallery. I have everything working upto the point where I need to populate the gallery.

    I examine the milestone variable below and it is as expected with first set of values from my json feed.

    Fails everytime with newView.subviews undefined.

     

    I have no idea whether the text boxes came before the image (i.e. what is [0] and what is [1] etc) so i deleted everything from the gallery, started again and only added an image. So it must be at [0]. but it still shows as undefined in inspector

    Any ideas for me to get this going. I have spent a day so far and have seen exciting progress, now i am stuck on the last step.

    Thanks!

    Paul

     

     

    this.cellAtIndexInContainer = function ( container, index) {

       var newView = iAd.Archiver.restoreFromArchive( this.archivedPrototypeCell );

       var milestone = this.milestones[index];

       var imagePath = milestone.image || '';

      

    // fails on next line - newView.subviews undefined

       newView.subviews[0].image = iAd.image.imageforURL( imagePath, false); 

      // newView.subviews[0].text = milestone.date || '';

      // newView.subviews[1].text = milestone.title || '';

      // newView.subviews[2].text = milestone.description || '';

      

        return newView;

    }

  • by markmalone,

    markmalone markmalone May 14, 2014 9:30 AM in response to KPWatts
    Level 2 (210 points)
    May 14, 2014 9:30 AM in response to KPWatts

    It's most likely failing because this.archivedPrototypeCell is undefined.

     

    In the demo, it's defined before the load of the XML content using:

     

    this.archivedPrototypeCell = iAd.Archiver.archive(galleryView.cellAtIndex(0));

     

    This grabs the first cell in the gallery and creates a freeze-dried copy and stores it on a dynamically created property on the gallery called archivedPrototypeCell.  The call that's failing for you grabs the freeze-dried copy for the cell, thaws it out then it's ready for you to set the cell's content.

     

    Cheers,

     

    -Mark

  • by KPWatts,

    KPWatts KPWatts May 14, 2014 2:30 PM in response to markmalone
    Level 1 (0 points)
    May 14, 2014 2:30 PM in response to markmalone

    Thanks for fast response Mark,

    I have included the only other two pieces of code in my project. As you can see i did freeze my first cell.

    I can see "newView" is a valid object after the thaw in the inspector - just subviews are not defined. Maybe something to do with the way the gallery and first cell and image were created?

     

    One other question. I have 4 milestones in my json feed, so "numberOfCellsInContainer" is returning 4. Even though i cannot place my new images or text directly in the gallery, this code should place 4 identical copies of cell 1 in the gallery. This is not hapenning either. When i run (without the subviews lines so i do not get any errors) i just get the one image. Times like this i have to remember computers are logical and do exactly what i tell them to do and i must have done something wrong!

     

     

     

     

    this.onViewControllerViewDidLoad = function (event) {

              // Code here for the "Page Did Load" event.

              // Called when the page has loaded. Perform additional initialization of page content here.

        var galleryView = this.outlets.timelineGalleryView;

        galleryView.dataSource = this;

        this.archivedPrototypeCell = iAd.Archiver.archive(galleryView.cellAtIndex[0]);

       

        var jsonPath = "file:///Users/williamwatts/Documents/iad/paul.json";

        this.milestones=[];

      

        var req = new XMLHttpRequest();

        req.open('GET', jsonPath, false);

        req.send(null);

       

        if(req.status == 0)

        {

           var myJson = req.responseText;

           var jsonObj = JSON.parse(myJson);

           this.milestones = jsonObj.milestones;

           galleryView.reloadData();

        }

    };

     

    this.numberOfCellsInContainer = function (container) {

       return this.milestones.length;

    };

  • by markmalone,

    markmalone markmalone May 16, 2014 2:10 PM in response to KPWatts
    Level 2 (210 points)
    May 16, 2014 2:10 PM in response to KPWatts

    Hmmm....Did you double-click on the cell and drop in the image object or just lay it on top.  It's gotta be inside the cell so it's included in the serialization.  Not sure what else it could be.

     

    Code for the page that works for me is:

     

    this.milestones = [];

     

     

    this.onViewControllerViewWillAppear = function (event) {

              // Code here for the "View Will Appear" event.

     

        // path to my server

        var webservicePath = "http://localhost/myfeed.json";

     

        // asynchronously load the webservice

        var xmlLoader = new iAd.XHRLoader(webservicePath);

        xmlLoader.delegate = this;

        xmlLoader.load();

     

     

    };

     

     

    // Called when the XHR call failed

    this.loaderDidFail = function ( loader, error ){

        alert("Load failed with error: " + error);

    };

     

     

    // Called when the XHR call was successful

    this.loaderDidComplete = function (loader){

     

        var galleryView = this.outlets.timelineGalleryView;

        galleryView.dataSource = this;

     

        // grab and store the content returned

        var json = loader.content;   

        var jsonObj = JSON.parse(json);

        this.milestones = jsonObj.timeline.milestones;

     

     

     

        // store an archived copy of the prototype cell

        this.archivedPrototypeCell = iAd.Archiver.archive(galleryView.cellAtIndex(0));

     

        // tell the gallery to update itself

        galleryView.reloadData();

     

     

    };

     

     

    this.cellAtIndexInContainer = function(container, index) {

     

     

        // create a new instance of the prototype cell

        var newView = iAd.Archiver.restoreFromArchive(this.archivedPrototypeCell);

     

     

        // event data at the index

        var milestone = this.milestones[index];

     

        // get the path to the event image

        var imagePath = milestone.image || '';

     

     

        // create an image object and assign to the image property of the imageView

        newView.subviews[3].image = iAd.Image.imageForURL(imagePath, false);

     

        // set the text values

        newView.subviews[0].text = milestone.date || '';

        newView.subviews[2].text = milestone.title || '';

        newView.subviews[4].text = milestone.description || '';

     

     

        return newView;

    };

     

     

    this.numberOfCellsInContainer = function(container) {

     

        return this.milestones.length;

    };

     

    and the cell hierarchy looks like this:

     

     

    Screen Shot 2014-05-16 at 2.07.05 PM.png

     

    -M

  • by KPWatts,

    KPWatts KPWatts May 17, 2014 12:16 AM in response to markmalone
    Level 1 (0 points)
    May 17, 2014 12:16 AM in response to markmalone

    Thanks so much for the code. So i had 2 stupid problems that in hind sight make sense, but at the time I was sure i was right. Arrays are always square brackets and first letter is always lower case. However i see now it is not an array it is a parameter and you only lower case on the methods not the functions.

    1. this.archivedPrototypeCell = iAd.Archiver.archive(galleryView.cellAtIndex(0)); // I had [0]
    2. newView.subviews[3].image = iAd.Image.imageForURL(imagePath, false);// i had iAd.image not iAd.Image!!

    So now when i preview in safari it all works perfectly!

     

    Thanks!!

    Paul


  • by markmalone,

    markmalone markmalone May 17, 2014 7:28 AM in response to KPWatts
    Level 2 (210 points)
    May 17, 2014 7:28 AM in response to KPWatts

    Ah, the perils of a case-sensitive language.

     

    Glad you're over the hump!

     

    -Mark

  • by imaxinant,

    imaxinant imaxinant Jun 19, 2014 11:30 AM in response to Robbie N
    Level 1 (0 points)
    Jun 19, 2014 11:30 AM in response to Robbie N

    Hello,

     

    I'm also trying to control a Gallery with JS, and I would like to know if is it possible to setup the "sensitivity" of a gallery.

    I would like users can do a swipe gesture softer than required by default.

     

    Hope you can understand me...

     

    Thanks in advance!

  • by markmalone,

    markmalone markmalone Jun 19, 2014 12:02 PM in response to imaxinant
    Level 2 (210 points)
    Jun 19, 2014 12:02 PM in response to imaxinant

    The Gallery View looks pretty much set up to match the performance characteristics of a native device scrollview with paging but you may get closer to what you want by using a Scroll View object in iAd Producer. There are hooks in the Scroll View to track movement and acceleration.

     

    Cheers,

     

    -Mark

  • by imaxinant,

    imaxinant imaxinant Jun 23, 2014 2:41 AM in response to markmalone
    Level 1 (0 points)
    Jun 23, 2014 2:41 AM in response to markmalone

    Thanks a lot for your reply, Mark!tri

     

    I've got my iBook Widget developed and I suppose developing it again would be so much work... I'll try it next time

     

    Thanks!