As Magna Carta is a solid block of text, one of the ideas we’ve had from near the start is to be able to filter which overlays are on the screen. The main aim of this was to increase usability and give the user an opportunity to read certain clauses that they might be interested in (based on which filter they choose).
Below is an image of the initial state of the app before starting this process. It shows how it looks with all the clauses highlighted. While we think it actually looks pretty cool, it can sometimes be difficult to touch the icon you want without zooming in, so adding the filter option should help with this problem.
To filter the overlays, we wanted a menu that the user could pull out from the side, and it would be placed on top of the Magna Carta image. To do this we used a sideViewController (loosely following a tutorial here). The sideViewController is a separate viewController, but when it shows, it only shows on part of the screen on top of the current viewController – funnily enough this is exactly what we wanted.
To start with we started with playing with icons to act as a button for showing the menu. While doing it, we thought it could be interesting to use the cross icon from the assets made by RedBalloon – keeping with a consistent style. We put it in and realised it didn’t look as good as we had hoped. We also thought that users might not realise it is actually a button used to show the menu.
After that we went back to our original idea of using the more traditional burger icon and it was just as beautiful as we had hoped. We felt the burger icon was the best choice to use in the app as recently it has become synonymous with representing a menu or to show more details, which is what we wanted it to do.
When the sideViewController is first set up, it consists of a blank tableView. We added some colours to our tableView before we screenshot the blank version (We didn’t think it would be worth it to go back and remove the colours, so just imagine what it would look like in white).
Now it comes to the fun part – filling the tableView with information!
The prototype cell (and the colours) was set up in the ever difficult to use storyboard. While we had done many of the other things programmatically (The detailView for example), neither we or our tutors had worked with the splitViewController before so it would be easier to let Xcode hold our hand through the process. We added a label which would be used to hold the title for each filter. This label was given a unique identifier so that it could referenced in the code to populate the table.
An array of strings was created with the 15 categories used to filter the overlays, [“Key Clauses”, “Church”, “Feudal”, “Forest”, “Jews”, “Justice”, “King’s Officers”, “Miscellaneous”, “Money”, “Peace”, “Trade”, “Wales & Scotland”, “Women”, “all”, “Hide Overlays”]. Similarly, another array filled with the numbers 1-15 was created. This array would be used to references the images. All of the icon images files were names 1.png, 2.png etc. I did this because of a certain way that Swift works. When accessing an image file, the extension doesn’t needed to be added to the end (i.e. 1 would be associated with 1.png) – a specific advantage over using a .jpg file in the app. The .png files also allow for transparent backgrounds which is what we needed.
A function is used to make the length of the table the same length of the array. This make it easy if we ever need to add of remove a category from the array – making it more responsive to change and is good practice to get into rather than setting static values. After this, another function iterates through the array/table and changes the label text to be the same as the current index of the array. A similar thing is done to place the images next to the text label.
After this a function is used to similarly iterate through the table and detect which one is selected when touched. Here is where a specific function was added to get the filter action to work.
Turns out, it’s more difficult than we thought to get one viewController to communicate with another. This is where we had to show creativity and originality in our programming. We wanted to use the sideViewController to do something it wasn’t supposed to do. The usual implementation would use the menu to travel to different view controllers. However, we wanted a function on one viewController to affect something on another.
To do this we had to use NSNotificationCenter (following this tutorial). This feature works similarly to a radio broadcast tower. One view is set up to transmit a unique signal and can send data, then the other view is set up to recognise and receive this unique signal then do something with the data it receives.
The first step was creating a special notification key – something unique to this app and the data it was sending. For this I used:
let mySpecialNotificationKey = “This category was chosen”
I then made a function which would be used to send the data across. This function takes a specific type of data, an array of strings. This string is the data used to filter the clauses. I’ll get into more detail about why its an array later.
In the same function that detects which row is selected, the function is called. When a filter row is selected, the string from that row is send off in the function as the piece of data. For example, if the user tapped the “church” category. the string “church” would be sent off by the function to be received by the other viewController.
This line was then added to the original view so that it can listen out for the special notification key. Once it hears the key (when a filter is chosen) it will run a specific function as a reaction.
This is the function it runs. It has to convert the data it receives back into an array of strings so that it can be used. It then places this information into the onlyShowClausesWithCategory function so that it can search for which clauses have this category, then show them. as it is an array, it needs to know which part of the array to select, so .first is added to the end so it always selects the first item in the array. The array will always only have one item in it because only one category can be selected at once. I added a print line in the log so I could see when/if the information was being sent across.
Here is the onlyShowClausesWithCategory function which is used to filter the clauses. It looks very complicated – it is – but I will try my best to explain the basic premise of how it works and why it is needed. The function accepts one value, which is the category. This is the category which will be shown when selected. Inside the function, two arrays are made, overlaysToHide and overlaysToShow. As you can probably guess, this function will sort though the overlays to decide which ones are in the right category to be shown and which aren’t. The for loop iterates through the clauses and overlays, and searches the clause “category” array for the right category. If it finds the category in the array it will add it to the overlaysToShow array, and if it doesn’t, it goes into the overlaysToHide array. The arrays are then iterated through an animated, changing the opacity with a duration so that the hidden overlays will fade out, and the show overlays will fade in (if not already shown)
Similar to this, a function called onlyShowClause was made which has a similar sorting feature. However the difference here is that it is run when a clause is selected to see more detail. What this does is makes the ones that aren’t selected hide, and while the selected one remains. Below the two images show the Key Clauses category. Then the preface (first block of text) was selected which caused the other clauses to hide so that only one is shown.
We really liked this feature as it made it even clearer which clause the user is looking at. However there is one minor issue with this. If a clause is selected in the lower half of the screen, it be seen as still selected as the detailView is on top it of. At this point we don’t have enough time to come up with a work around as there are many other things that need fixing/ making and are more important than this small cosmetic issue.
If there was more time we would be able to play around with different ways to mitigate this issue. For example, we could make it so that if a clause on the lower half of the screen was selected, the detail view come down from the top instead. This seems simple enough but would require a lot more thinking and programming to get this to work.