iOS

Building a Custom Content View with UITableView and MapKit


This is a guest post by Sean Choo, the developer of Cureto. In this tutorial, he will show us how he implements the app’s article view using custom table view.

Hi everyone, I am Sean Choo, a Malaysian who is currently studying in Hong Kong. What bugs me all the time is: I always have difficulty finding good food to eat in Hong Kong. Back in Malaysia, I don’t have this worry because 1. I grew up there, 2. There are really lots of nice food in Malaysia.

All the apps currently available just couldn’t solve my problem. So I think about it and realize that most of the good food I’ve eaten in Hong Kong are either discovered by myself, or introduced by my friends. And hence I set out to make an app so that my friends and I could introduce and convince each other on good food in Hong Kong. I have just published this iOS app on App Store recently, it’s called Cureto. The website for this app is here. You can also read the design philosophy here.

Cureto App

I see this app as an artwork. I want it to be pretty, the experience to be relax and enjoyable. If you have downloaded the app, you can see each food introduction is in fact an article. And to make reading pleasant, I have put in a lot of time designing the article. In this tutorial, I am going to share how I use UITableView to render an article shown below.

First, download the starter project here and open Delicious.xcodeproj. You will need Xcode 7.3 and Swift 2.2 or above.

Dissecting an Article

Dissecting an Article in uitableview

Take a look at the above photo. An article view consists of a Cover Photo, a Title, a Main Content, and a list of Sub Contents. To design a view like this, I use a custom table view, and create three prototype cells for the cover photo, main content, and the sub content.

To model this structure, let’s create two files in the Models folder: Article.swift and SubContent.swift. You can right click the Models folder, choose “New File…”, and then create a Swift file.

Create two files in xcode

In Article.swift, insert the following code:

The Article class has several properties including title, cover photo, meal type, restaurant location, and sub contents.

In SubContent.swift, insert the following code:

Each subcontent contains a photo and paragraphs of text. So we define the corresponding properties.

Next, open ArticleController.swift under the Controllers folder. The ArticleController class, which is used to render an article, is associated with the table view controller in Interface Builder.

In the class, add a currentArticle variable, then create a initializeArticle() method and call it in viewDidLoad().

The currentArticle variable is used to hold the article being displayed. The initializeArticle() method helps setup the article details, and it initializes a sample article after the view has finished loading.

Now that you’ve finished the implementation of the Article class, we are going to setup the UITableView for the article. First of all, add these 4 lines in ArticleController.swift.

First, we declare two constants for holding the screen width and height of the device. And we make use of the self sizing cell feature by setting the row height to UITableViewAutomaticDimension and giving the table view an estimated row height.

Next, let’s setup the methods for rendering the table view in ArticleController.swift. In the ArticleController class, insert the following method:

Each article contains the following sections:

  1. The first section is for the cover photo.
  2. The second section is for the article title, plus the main content.
  3. The rest of the section is for the subcontents.

Therefore, the total number of rows is 2 + article.subContents.count.

For the cover photo row, we have to calculate the row height. For example, if a cover photo is 4w : 3h in ratio, height ratio will be 3 / 4 = 0.75 and row height would be screen width (e.g. 375 for iPhone 6S) * 0.75 = 281.25. For the rest of the rows, it is good enough to use automatic row height.

First, instead of using a normal string for text in the article, we use NSMutableAttributedString, that the article will be more pleasant to read. The attributedContentFromText() method is a helper method for converting a string to a NSMutableAttributedString. The rest of the code is pretty straightforward. We simply configure the cells for cover photo row, title/main content row, and the sub content rows.

Now it’s ready to have a quick test. Run the app, and you should now have something like this:

cureto article view

Yay! You have just created a very basic layout of the article. The font size and line spacing is just right to read. Then, you will have the urge to eat at this restaurant. But wait, where is this restaurant? Yes, we need a map, and perhaps also the restaurant name and address. Moreover, we need to acknowledge the author of this article too. To do this, we are going to use a footer for this UITableView.

Adding a Map to the Table View Footer

Now, we are going to add a footer for the UITableView. The starter project already came with the UI design of the table footer. You can refer to ArticleFooterView.xib for details. To implement the footer view, add the following lines of code right below the initializeArticle() method of ArticleController.swift:

Then, in viewDidLoad(), add the line of code highlighted in yellow to call up the addFooterView() method:

Run the app again. Scroll to the bottom and you will have something like this:

article view cell with maps

Seems like we’re done! But no, why the map not showing the expected location of the restaurant? Of course, it’s because we haven’t implemented it. You now have an empty MKMapView in the footer. We will now move on to add a pin to the MKMapView. But first you will have to enable Maps in Capabilities.

xcode add maps capability
add maps to xcode project

Back in ArticleController.swift, right below import UIKit add a line of code to import MapKit:

Then, for the method addFooterView(), please update it to the following code so as to add the logic to render the correct location:

Assuming you have some knowledge of MapKit, here we simply set the region of the map to the location of the restaurant. Then, we put a pin on the exact position of the restaurant.

Editor’s note: You can refer to our Swift programming book if you want to learn more about MapKit.

Great! Let’s run the app again. You should have something like this:

uitableviewcell with maps

Adding an Action Menu

Now the article looks complete! But I feel one thing is missing: we need an action bar for people to take actions, such as giving a like to this wonderful article. I would also like to share how I use extension in Swift to customize existing class such as UIView to carry out the desired animation, so that you can also write your own extension in the future!

For the starter project, I have created the menu bar in ArticleMenuView.xib. But I want the article menu to swipe up from the bottom of the screen instead of just popping up from no where. Let’s get started to implement it.

First, add these 3 lines (highlighted in yellow) in ArticleController.swift:

Here we just add:

  1. A variable to hold the Article Menu
  2. A boolean to check whether the Article Menu is hidden
  3. A variable to be used for hiding the menu on scroll later

The Article Menu slides up from the bottom of the screen when the article appears. To do that, we add a custom extension for UIView. Create a new file named UIViewExtension.swift and put it below AppDelegate.swift in the directory.

Next, insert the following code in UIViewExtension.swift:

Then, in ArticleController.swift, add these 4 methods right below addFooterView():

After that, right under viewDidLoad(), add the following methods:

In the above code, we invoke the addArticleMenu() method in ViewDidAppear(), so that we bring up the article menu when the article appears. Conversely, we call the removeArticleMenu() method after the article disappears. We also implement the scrollViewDidScroll method to hide the article menu when the user scrolls down the article view. And we will unhide the article menu when the user scrolls up again.

Summary

Cool! You have created a food article using UITableView. I hope you enjoy reading this tutorial, and understand how to implement a simple article view using custom table view. For complete project, you can download it from GitHub.

iOS
How To Download Older Version of Xcode
iOS
Introduction to Custom View Controller Transitions and Animations
iOS
Building a Geo Targeting iOS App in Swift
Shares