bookshelf_thumb

Back to Blog

ShinobiEssentials: an accordion off the shelf

Posted on 12 Nov 2013 Written by Andrew Polkinghorn

One of the great components that’s part of ShinobiEssentials is the Accordion and in this blog I will show you how easy it is to make your own!  First I’ll go through how to set up the SEssentialsAccordion, then I’ll explain how to handle passing it the views that open when each section is clicked and finally I’ll show you a few styling tips on how to get the most out of your accordion.

screenshot.png

This blog post doesn’t take you through the whole setup line-by-line so before reading on it’s probably a good idea to clone or browse the full project on GitHub, or download the zip, so you can see how it all fits together.

If you haven’t already got a trial for Essentials… What are you waiting for! Download a free trial of Shinobi Essentials today!

The Set Up:

To create an SEssentialsAccordion you need to set four things:

  • Datasource
  • Sections
  • Type
  • Delegate (optional)

The Datasource:

The purpose of the Datasource is to supply the accordion with all the data it needs to function. An SEssentialsAccordion only requires one method in its datasource which is “-accordion:contentForSection:”. This method returns the UIView that will appear when the SEssentialsAccordionSection parameter is opened. In this BookShelf app the UIViews are prepared when the app first loads using an NSMutableDictionary to store the UIViews using the NSValue of the corresponding SEssentialsAccordionSection as the key.

The following code can be found in the “setupData” method in the BookShelfDataSource class and shows how to create an SEssentialsAccordionSection and add it to an NSMutableDictionary.

for(int i = 0; i<[_archive books].count;i++){
    Book *book = [_archive books][i];
    BookShelfView *bookView = 
        [[BookShelfView alloc] initWithFrame:CGRectMake(0,
                                                        0,
                                                        BOOKSHELF_VIEW_WIDTH,
                                                        BOOKSHELF_VIEW_HEIGHT)
                               withBook:book];
    SEssentialsAccordionSection *section = 
        [[SEssentialsAccordionSection alloc] initWithFrame:CGRectMake(0,
                                                                      0,
                                                                      BOOKSHELF_VIEW_WIDTH,
                                                                      SECTION_HEIGHT)
                                             andTitle:book.title];
    // Style section headers
    ...
    [_dataMapping setObject:bookView forKey:[NSValue valueWithPointer:CFBridgingRetain(section)]];
    [_sections addObject:section];
}

Once the dictionary has a UIView for every section in my accordion when each section is clicked the “-accordion:contentForSection:” method can return the corresponding UIView. In this project it uses the NSValue of the SEssentialsAccordionSection parameter as the key.

The following code shows how I have implemented this method and can also be found in the BookShelfDataSource class:

-(UIView *)accordion:(SEssentialsAccordion *)accordion contentForSection:(SEssentialsAccordionSection *)section
{    
    return [_dataMapping objectForKey:[NSValue valueWithPointer:CFBridgingRetain(section)]];
}

The Sections:

The sections array is an array of all the SEssentialsAccordionSections that are going to be inside the accordion. In this example each section represents a Book and when clicked the UIView appears showing the Book’s cover.

The following line shows how I set the sections on my accordion and can be found in the  “setupUI” method in the BookShelfViewController:

[_accordion addSectionsFromArray:[_dataSource sections]];

The Types:

There are a two different SEssentialAccordionTypes to choose from Fixed and Flexible. In this implementation I have chosen Flexible as it doesn’t stop you from scrolling to the end of the BookShelf when a book is opened.

The following line shows how I have set my accordion’s type and can be found in the  “setupUI” method in the BookShelfViewController:

[_accordion setType:SEssentialsAccordionTypeFlexible]; 

The Delegate:

The delegate allows you to add some custom behaviour to the accordion in response to specific events. In the bookshelf app I set the SEssentialsAccordionDelegate so I could override the”-accordion:willOpenSection:” method to implement the ‘one section open at a time’ behaviour. This delegate method gets called before an accordion section is opened.

Here is the how I implemented that method which can be found in the BookShelfViewController class:

- (void)accordion:(SEssentialsAccordion *)accordion willOpenSection:(SEssentialsAccordionSection *)section {
    for(int i =0; i<[_accordion sections].count;i++){
        SEssentialsAccordionSection * section = [_accordion sections][i];
        if(section.open){
            [section setOpen:NO];
            i = [_accordion sections].count;
        }
    }
}

The Styling:

The SEssentialsAccordion’s style is completely customisable, in this project I have customised the section header style. I gave them all the same font but assigned them different section header and section background colours which were taken from the related Book object.

The next block of code shows how I customised my section style and can be found in the “setupData” method in the BookShelfDataSource class:

        // Style section headers
        [[[section header] style] setBackgroundColor:book.spineColor];
        [[[section header] style] setSelectedBackgroundColor:book.spineColor];
        [[[section header] style] setSectionBackgroundColor:book.coverColor];
        [[[section header] style] setFont:[UIFont fontWithName:@"GillSans" size:30]];
        [[[section header] style] setFontColor:[UIColor orangeColor]];

Summary:

Here’s a quick recap of what to do to make your own SEssentialsAccordion:

  • Once initialised, assign your accordion a datasource, delegate, sections array and type.
  • Inside your datasource, make sure you implement the “-accordion:contentForSection:” method.
  • Customise each section using the “style” property.

Now you should be able to make your own SEssentialsAccordion. You can browse the finished project on GitHub, or download the zip.

If you don’t already have access to our ShinobiEssentials component download a free trial today!

Back to Blog