At the beginning we mentioned that our app is now going to be a separate app that is designed for iPad and going to be an installation that sits next to the Magna Carta document. We felt it necessary to provide Salisbury Cathedral with a complete packaged mobile application. That includes the actually app itself packaged with all the features the client wanted but also a Splash screen so when the app is opened (and for our case a long time) it shows an image of what the app is that’s being opened and an Icon to display on the launch pad on the iPad device.
Using the design guidelines set by Salisbury Cathedral we created these elements that conformed to the styling. Making sure that all the colours that were used were colours that we defined by the guidelines, all the fonts that were used were the same as the other work that will be displayed in the exhibition and making sure all image assets are copyright free or the cathedral hold the copy right for them.
Below the design that was created for the app icon. Using a online icon generator I was able to make the image Icon on a square 1024x 1024 then it created the images into all the sizes that we need for the app icon to work.
See below the exported images that all the different sizes that are needed within the app.
Of which can be then put into the imageAssest’s appIcon file which when xCode builds the app it will take the images and compile them into the app. See below all the images in the asset file for an iPad device, we could also put in the sizes for iPhones however as we are explicitly making it for an iPad we haven’t included these.
The method for the splash screen was very similar, however there wasn’t a website that created all the different sizes which would mean I would have to export all the different sizes myself. Luckily enough there is a LaunchScreen.xib that allows you to create the splash screen on a storyboard* which I added a UIImageView to place the same image as the app icon. See below splash screen.
However as the splash screen is scaleable depending on what iPad model it is. Therefore we have separated the background image to the text. This way the background can be scaleable but the text will remain the same size and centred by using constraints within the launchscreen.xib.
* This is a self-declared storyboard which is for a launch screen it has the same layout however it doesn’t hold the same properties as a storyboard.
One of the big things in iOS is having small animations for transitions. These seemingly insignificant effects make a great different to user experience within the app.
First up was the detailView. This is essentially a view which we translate its y coordinate from off screen to on. The original for this was animating with duration. This a made the view smoothly slide up from the bottom. We changed this to be a spring animation so that when it popped up, it bounced at the top of its appearance. This made it a little more fun to use and looked a lot better in our opinion.
I mentioned in another post about making the overlays fade in and out. When a category filter is chosen from the menu, the ones not in that category fade out and the ones that are in the category fade in. This is done by animating the alpha channel of the overlays when the hide or show functions are run. Similarly, when a clause is chosen to show more detail, the ones that weren’t selected fade out, and fade back in when the detailView is closed.
All these effects can be seen in the gfycat video below.
Upon playing with the app, I noticed that if you were zoomed in and then were to change the category, you might not see that anything on the app had changed as the overlays update of screen. I decided to add an animation which zoomed out the view when a category filter is chosen, this forces the user to see the changes and gives a smooth transition back to an overview of the document.
Here you can view it in action, apologies for the sideways video and shoddy filming (it was done on my phone to make things quicker)
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.
Up until now we only ever had one overlay for each clause. This was because we didn’t actually know where the clauses were on the document so we built it using this method. After we got send the information of where the clauses were, we were able to mark down the coordinates and size of each overlay. As some clauses span over multiple lines, it meant that multiple lines per clause needed to be drawn – completely changing how the app functions.
Each overlay has an x & y coordinate, and a width and height. Each clause may consist of up to 4 overlays. Each overlay in each clause must go to the same detailView for the correct clause details. These were the basic steps of what was needed to get this to work.
First step was to create a “Clause” class, this has a name, a category, a colour, and the details in the detailView. Similarly, an “Overlay” class was needed which would work with the Clause class. The Overlay class has a member of Clause, where it gets it’s colour and so it knows which clause it is associated with. The overlay is also given a frame, the x & y, width and height, so that the box can be drawn on the document image.
In the main viewController an array is made where the clauses are mapped to the overlays. Before, when there was only one overlay per clause, the array was iterated through adding a tapGestureRecogniser to each overlay so that each go to different clauses. Similarly here, the overlays are iterated through and added to the clauses (I’m not entirely sure how this works, but I have a vague understanding. Marc helped a lot with this part as it was very confusing, and needed to be done quickly due to the deadline).
After this is was a matter of filling the arrays so the overlays and clauses can be made. Here is an example of what it looks like:
At the top, two variables were made to store the colours. This was done for two reasons: Firstly, to make it easier so the RGB values didn’t have to be repeatedly typed out, and secondly, so that the colour values could easily be changed without having to do it for each clause. As you can see by the comment, at this stage the colours aren’t fully decided on; we have something close to what we want but as they have different opacities, it doesn’t look precisely what we want it to look like. Minute attention to detail like this is a good professional practice to have so that small mistakes aren’t repeatedly made.
Each clause in the array has a number of details. The name is used for the title in the detailView, the category (often categories) will be used to filter the clauses once this part is created, the detail is the body text for the detailView and the colour is the colour of the overlays for that clause. Below that comes the overlays for which CGRects are used – similar to what we had before but this new method allows us to have more than one.
SWIFT: The NEW language to create applications on iOS and OS X.
Previously developers used Objective-C to program the apps that we love and use. However, in 2014 Apple created their own language for developers to use to create applications for iOS and OS X. The code works side-by side with objective-C which allows the code to run fast. It is concise and is fun to code.
Whats the Difference between swift and Objective-C ?
Except for the syntax and a lot of new paradigms. Swift is very easy to get to grips with and there were a few things that made the code easier to write than Obective-C. Unlike Obective-C, Swift doesn’t need the use of brackets when defining parameters or semi colons to end the line of code. In addition the code isn’t pedantic and doesn’t return errors when spaces are missed out or the sentences are structured in a different order. This allows the programmer to focus on the app rather than the code.On the performance level, Swift is more impressive than Objective C. This is because Objective C does not allow a compiler to do a lot of optimisation due to its dynamic nature. With Swift, there is much more room for optimisation at compile time. Apple states that Swift is 2.6 times faster than Objective C code. Overall, it results in much better performance. There is still a lot of debate on the web, but it’s mostly about tools and less about language – buggy issues and surprises due to the young age of Swift.
How is Objective C better than Swift?
First of all, Swift has all of the capabilities of communicating with Objective C code, as you can incorporate parts of objective-C within a swift project. However, libraries are not the most pleasant to work with. There are some challenges to constructing the Swift code, e.g. many nested blocks to unwrap the optional values. Overall, it ends up becoming a huge tree – some call it a pyramid of doom. There are ways to overcome this, but it is still not perfect. Talking about advantages of Objective C would likely lead to discussing Swift pain points, because there is not much Objective C has that is better than Swift.
We use swift because it is the future of coding. It has only been around for a year however it has already made massive advancements on Objective-C and once the buggy issues get sorted it will be far superior.
After weeks of waiting we finally got sent the real image of Magna Carta which were going to use in the app. This image was a much higher resolution than the one that we were using currently, which we got from the Salisbury Cathedral website.
The Cathedral had this picture taken specifically for the 800th anniversary of the signing of Magna Carta so it was essential that we used inside the application as a springboard for the navigation of the causes.
There were some technical limitations with the image that they gave us. The original image was over 34,000 pixels wide which would allow the user to zoom in and see details in the document that could never be seen with the naked eye. Due to the large image size, the size of the file is also incredibly high which would make the size of the application much larger. For us, however, this isn’t that much of a problem at this point as the application will only be used by Salisbury Cathedral and would not be available for general members of the public download.
We tried putting this image straight into the application but due to its large size, the iPad simulator wasn’t able to ever load the image. This meant had to re-evaluate our approach to having a large zoomable image inside the app.
We put the image into photoshop and resized it down to 8000 pixels wide. Then we were able to compress it while saving it as a PNG file as to not lose too much of the image quality. While being significantly smaller than the old image size, it still allowed the user to zoom in considerably, and see more detail than could be seen before. While the client may not be too pleased with this limitation, it is something outside of our control due to our lack of programming expertise and the limitations of our methods.
It was suggested to us that, if we were much more competent with the software, we would be able to load the image as a series of tiles. This would mean that only the tiles that are on the screen would be loaded at any given times, thus reducing the work load on the device and allowing for a much larger image size. This would work similar to how the SWIF mapkit loads each piece of the map when requested. However due to our inexperience, and the time constraints of the project, this is not something we are able to explore.
As we now have the size and resolution of the image we are going to use in the application, we can now get started on finding the locations of each clause within the document. Our client has provided us with an image demarcating the start of each of the 62 causes allowing us to translate this information to our new image. This process will require us to find the X and Y corners of the top left corner of each clause as well as the width and height. These are the details needed in the swift code to allow us to draw the overlays on the app. In some cases a calls will go to meaning that it will require more than one rectangle to be drawn. As it stands we currently don’t know how to solve this problem in the code but it will be something that will be looked at in future prototypes.
For the app, we wanted to create a sidebar menu so the user will be able to select certain clauses within the app and hide other clauses. These categories included; the main clauses, church related, money orientated, justice, peace, women and royalty. As we are using a very high quality image of the Magna Carta for the basis of the Magna Carta, we were very keen on creating a function that will allow the user to hide the overlays, that display the translation and contextualisation for each clause.The reason behind this is that there are tiny details within the app that aren’t visible until you zoom into the document; for example a piece of wood stuck into the parchment. We feel that these details are valuable to the heritage of the document and an interesting factor that people may not consider. Also as all the clauses will be highlighted using overlays it could be very distracting and may take away the impact and power of the document, therefore this function will limit this.
Some of the examples of different side bars that we have looked include;
From these examples we found that the applications use libraries that have been already coded and import them into the app, very similarly to the map kit Apple supply to create apps with maps. We looked at an open source library called SWRevealViewController to build the sidebar menu. Though the library was written in Objective-C, however it is possible to integrate it into any Swift project. This is done by accessing and interacting with Objective-C classes using Swift.
As we hadn’t created side bar menu’s before we decided to create a separate project working out how the side bar would programmatically work then after we had a prototype for the side bar, we would amalgamate the two together.
Below is a screenshot of the Storyboard for the prototype. It uses the side bar menu as a new screen which which is then navigated through the navigation controller to the views of the various screens. The custom SWRevealViewControllerSeguePushController (which is the side bar menu view) segue automatically handles the switching of the controllers. This can be seen from the lines connecting the view controller to the navigation controller to the clause views.
Below we can see, the SWRevealViewController provides a method called revealViewController() to get the parent SWRevealViewController from any child controller. It also provides the revealToggle: method to handle the expansion and contraction of the sidebar menu. We set the target of the menu button to the reveal view controller and action to the revealToggle: method. So when the menu button is tapped, it will call the revealToggle: method to display the sidebar menu.
The premise behind this side bar menu is that it uses segues to navigate from one screen to another which works well for the majority of Apps however our Magna Carta app will be using UIview’s within the same screen therefore the Side menu Bar that we have created here won’t be able to simply pull together with our original prototype. Therefore hopefully with the help of Marc or Kyle we will be able to use the menu that we have created, adapt it a little and be able to have a menu that works within our Magna Carta app.