As we come up to the final week, we’re just adding the final touches to the application to make sure that it is the best product we can provide for the client.
Last week we were given the final translations and contextualisations to use in the app from the client, so the first step was to add these into the code. After we did this, we noticed that they were significantly smaller than before. Because of this, the detailView seemed far too tall compared to the text inside it.
Originally the detailView was 500 high. This value was just an estimate size as it stuck throughout most of the development. First we tried lowering this down to 300. This worked well with some of the shorter clauses as the box didn’t drown them, but with the preface and suffixes, it seemed to be far too small and required too much scrolling. We went for the final option of 400 high. This was a good middle ground between being small enough for the shorter clause translations and big enough for the larger ones.
While doing this, I went through and cleaned up the code. This meant adding comments to functions and deleting excess line breaks to make it neater and easier to read. Commenting the functions and code is essential when handing the project over to someone else, and is always good practice to do just for myself. It is a way of always knowing what the code does and why it works/ was included. Sometimes what seemed like a simple thing to write at the time can seem complex and difficult to understand a week later. Commenting the code speeds up the workflow and is a good professional practice to get into so the code is clear and easy to read, edit and understand.
I also removed the swiftyJSON.swift file from the code. This remained in there from when I experimented with using JSON to get the translations into the code. There were also some old image files left in the project folder from when I was testing for the best solution and images to use. It is good practice remove excess files and text to keep file sizes to a minimum. Its not good to bulk out the project with assets and code which aren’t even being implemented as it makes it cluttered takes up unnecessary space.
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.