Reconstructing The Secret App (Viewing the Secret) in 3 Days
Secret. The new app that lets you share your thoughts anonymously with your friends and people around you. It’s not so much a secret, but more like an anonymous cry for attention. The idea has tons of potential and the user base is quickly growing and although not many will agree that it’s especially useful - I personally think the app is beautifully designed, engineered and really is what the next wave of apps should look like.
For those who don’t know, Secret is an iOS only app (at the time I’m writing this blog post at least) created by David Byttow where users can post anonymously and their friends or people nearby can anonymously comment/like it. The more people that like the post, the more exposed it gets so it kind of acts like a filter for which secret posts are shown on the feed. For example, if I made a post and a lot of my friends liked it, it would be exposed to people in the city and show up on their feeds and if they like it, it would be exposed to more people around the country. Right now, the majority of secret posts that are popular are usually depressing secrets about individuals or people in the tech industry complaining about VC ventures and first world problems but the app is starting to gain traction and hitting headlines.
Regardless of the idea and how it works, I just couldn’t ignore how simplistic and beautifully the app was designed. I stumbled upon this blog: Design Details: Secret for iOS and got me thinking - what if I just spent 3 days to deconstruct and reconstruct the secret viewer part of the app as a side project? And that’s how I ended up here writing this blog post. I’ll scratch the surface on how I came about making each part of the secret viewer and if you really want to take a look or help look it better scroll straight down to the bottom for the link to the repo. Please note that this is most likely not how the app is created and that I hardcoded a bunch of stuff so it’s not exactly the prettiest code but it was essentially a discovery project for myself I’d like to share.
1. The Parallax & Blur
Notice how the secret gets blurred and moves in parallax with the bottom table view on scroll. It also rubberbands when the table view reaches the end.
Initial Thoughts:
This looked quite simple initially. The bottom view was obviously a TableView and the top part looked like a header for the TableView. I imagined the top part was simply a ScrollView and in the call back for scrollViewDidScroll for the tableView I would simply set the content offset of the top ScrollView by a factor of the distance moved by the TableView. For example, if I moved the bottom TableView by a distance of 5 pixels up, I would move the contents in the ScrollView in the header by a factor of that distance (maybe 0.5 so around 2 pixels) up. This didn’t end up working in the end because I needed the header to stick and if I simply made the ScrollView a header for the TableView, it wouldn’t stick at the top so this was done a bit differently later.
I imagined the blur to be a statically blurred image of the secret with an alpha of 0 and slowly faded in based on the distant scrolled by the TableView. This would give the illusion that the image was getting blurrier when in fact it was just a blurred image being faded in on top.
Implementation
My initial thought was a bit off for the parallax and the header. Although the parallax worked for the image in the ScrollView, because the secret app had a sticky header at the top when you kept scrolling - I couldn’t have a ScrollView as the TableView’s header because it would scroll past the top and there was no way to “stick” the header. I did something a bit different which I will explain in my next section. The parallax however was done the same way with the top image being part of a ScrollView and adjusting the ScrollView’s contentOffset by a factor of the delta for the bottom view’s delta in the ScrollViewDidScroll delegate callback. Same with the blur. I used a GraphicsContext to record the ImageView including the text label and buttons and then used Apple’s UIImage+ImageEffects category to apply a blur onto the image which I got from the GraphicsContext, set the alpha for that image to 0, added it as s subview on top of the original image and slowly faded it in based on the delta in ScrollViewDidScroll.
My final product looked something like this:
2. Sticky Header
Notice how the secret “sticks” to the top when the user keeps scrolling down to read all the comments.
Initial Thoughts
So remember when I said I couldn’t simply make the header of the TableView a ScrollView with the image? Well this was the problem. If I made the the header of the TableView a ScrollView there was no way I could make a “sticky” header like how it’s done above. My initial thought of approaching this was to have a tableView with the contentInset the size of the header at the top and a contentOffset up to where it started and then I could stick a ScrollView with the secret and Image behind it. Essentially, the TableView would be about the size of the screen and it would have a clear background so the user could see the secret which was behind the TableView. The problem with this approach was that I wouldn’t be able to tap any of the tool items since it would be behind the TableView and it would absorb all the touches. With the help from my coworkers - we deciphered a way of making a “sticky” header.
Implementation
The way I did it was to have a ScrollView the size of the screen. Within this giant ScrollView, I put a ScrollView about half the size of the screen at the top and a TableView on the bottom half. Let’s call the top ScrollView the SecretImageView and the bottom TableView CommentTableView. I disable scrolling on both the SecretImageView and the CommentTableView - and then I add the “Beach” image, the actual “Secret” text, and white toolbar buttons in the SecretImageView and populate the CommentTableView with comments. I only listen to the giant scrollView’s scrollViewDidScroll delegate call back. When I scroll down I simply set the contentOffset of the SecretImageView and fade in the blurred image until I reached a certain point. When I reach this point I keep adjusting the frame of the SecretImageView to scroll down with the user (since the user is scrolling down) to make it look like it’s “stickied”. For the CommentTableView, I do pretty much the same thing. I let it scroll with the giant ScrollView and then when it hits a certain point I adjust the frame of the CommentTableView to scroll down with the user and simply change the contentOffset to give the illusion of scrolling the contents. The final product looked something like this:
Bonus: If you look closely at the table view it fades near the edge at the top. This is by adding a gradient layer at the top of the table view (I use a container in this case) so it gives a subtle fading look at the top of the table view)
3. Zooming at the top of the ScrollView
Notice how the image zooms and expands when reaching the top of the ScrollView.
Implementation
For the remainder, I’m going to just show the implementation because these weren’t too hard to figure out but it was still fun making it.
A lot of apps do this now (Twitter, FourSquare, Secret, etc) and although my implementation may not be how everyone else does it - well, it was how I did it. In the ScrollViewDidScroll call back, I checked whether or not the content offset was < 0. If it was, then I would set the frame of the SecretImageView explicitly to expand - so something like:
_backgroundScrollView.frame = CGRectMake(CGRectGetMinX(rect) - delta / 2.0f, GRectGetMinY(rect) - delta, GRectGetWidth(rect) + delta, GRectGetHeight(rect) + delta);
where delta was the contentOffset.y of the giant scrollView and rect was the initial frame of the _backgroundScrollView.frame.
Pretty simple and has a cool effect when rubberbanding at the top of a scroll view.
4. Like Animation
Implementation
This one was super simple albeit not the cleanest thing I’ve written. I believe the best way to have done this would to use CAAnimation instead of the UIView animateWithDuration but I did it with the UIView animate functions anyways. All I did was chain multiple animations together in the completion block for each animation. The first animation being the scale large, then the scale tiny, then scale back to normal each with hardcoded durations and the EaseInOut function. I also gave the 2nd animation a bit of a delay to match what the app looked like and disabled the user interaction with the button until all the animations were completed.
I’m Not Done Yet!
This thing was hacked up in 3 days for fun so there are a lot of hacky things done in the code with magic numbers and bloated view controllers but if you want to take a look at the code click on the link below! I still have a few things left to do including:
Swipe Left to show the “more” menu.
Swipe Right to like the secret
Add a comment
Only allow scrolling when touching the CommentsTableView
But I wanted to show what I have so far and how I did it. Hope you enjoyed reading my blog and make sure to check out the source code below!
P.S. Yes, I drew all those assets myself with GIMP. And also if anyone can tell me what typeface Secret uses that’d be sweeeetttt!