قالب وردپرس درنا توس
Home / IOS Development / Implement Twitter iOS App UI (Update: Swift 3)

Implement Twitter iOS App UI (Update: Swift 3)



After using Twitter's iOS app for a while, I began to look at it with the developer's eye and noticed that some of the subtle movements and component interactions are very interesting. This gave me curiosity: how did you do on Twitter that?

More specifically, let's talk about the profile view: is not it elegant? It looks like a standard view, but if you look carefully, you'll notice that there's a lot more. The layers overlap, scale and move in interaction with the scrolling displacement, creating a harmonious and even ensemble of transitions … I was carried away, but yes you guessed it I love it.

Then let's do it and recreate this effect right away!

First thing first here is a preview of the final result of this tutorial:

Structural Description

Before entering the code, I will give you a brief understanding of how the user interface is structured.

Open the Main.storyboard file. Within the only viewer's view, you can find two main objects. The first is a view that represents the header and the other is a Scrollview that contains the profile picture (let's call it Avatar) and the other information related to the account like the username and feel button. The view called Sizer is just to make sure that the contents of Scrollview are large enough to enable vertical scrolling.

As you can see, the structure is very simple. Just keep in mind that I've put Header outside Scrollview, rather than placing it with the other elements, because though it's not strictly necessary, it gives the structure more flexibility.

Let's code

If you look closely at the final animation you will notice that you can handle two different possible actions:

1) The user draws down (when the content Scrollview is already at the top of the screen)

2) User scrolls down / up

This second action can again be split into four steps:

2.1) Scrolls up, The headline is customized to it when the Navigation Bar's default size and then picks it to the top of the screen.

2.2) Scrolls up, Avatar becomes smaller.

2.3) When the heading is resolved, Avatar moves behind it.

2.4) When the top of the user's name tag reaches e Header, a new white label appears from the bottom center of the header. The header image becomes blurred.

Open ViewController.swift and let us implement these steps one by one.

Set up the controller

The first is to get information about the Scrollview displacement. We can easily do that through the UIScrollViewDelegate protocol implementation of the scrollViewDidScroll function.

The simplest way to perform a transformation on a view, Core Animation uses homogeneous three-dimensional transformations, and uses new values ​​for the layer.transform property.

This guide on Core Animation may be useful: http://www.thinkandbuild.it/playing-around-with-core-graphics-core-animation-and-touch-events-part-1/. [19659002] These are the first lines of the scrollViewDidScroll feature:

 
     was offset = scrollView.contentOffset.y
was avatarTransform = CATransform3DIdentity
where headerTransform = CATransform3DIdentity

Here we get today's vertical offset and we initialize two transformations that we will set up later with this feature.

Pull down

Let's handle the pull feature:

 
  whose displacement <0 {

la headerScaleFactor: CGFloat = - (offset) / header.bounds.height
la headerSizevariation = ((header.bounds.height * (1.0 + headerScaleFactor)) - header.bounds.height) /2.0
headerTransform = CATransform3DTranslate (headerTransform, 0, headerSizevariation, 0)
headerTransform = CATransform3DScale (headerTransform, 1.0 + headerScaleFactor, 1.0 + headerScaleFactor, 0)

header.layer.transform = headerTransform
}

First, we check that the displacement is negative: it means the user pulls down, enters the drop-down menu.

The rest of the code is just plain math.

The header must be scaled so that the top edge is attached to the top of the screen and the image is scaled from the bottom.

Basically, the transformation is done by scaling and then translated to the top for a value that is equal to the size variation of the display. In fact, you can achieve the same result as moving the pivot point to the ImageView layer to the top and scaling it.

headerScaleFactor is calculated using a share. We want the headline to scale proportional to the displacement. In other words, when the displacement reaches twice the header of the header, ScaleFactor must be 2.0.

The other action we need to handle is Scrolling Up / Down. Let's see how to complete the transformation of the main features of this user interface one by one.

Heading (First Phase)

The current offset should be greater than 0. The header should be translated vertically after the displacement to it reaches the desired height (we will talk about shading blur later).

  headerTransform = CATransform3DTranslate (headerTransform, 0, max (-offset_HeaderStop, -offset), 0)

This time the code is very simple. We only transform the heading that defines a minimum value which is the point at which the header will stop the transition.

Shame on me: I'm lazy! so I have hard-coded numeric values ​​like offset_HeaderStop inside variables. We could achieve the same result in other elegant ways, and calculate UI element positions. Maybe next time.

Avatar

The avatar is scaled with the same logic we used for Pull Down, but in this case the image captures to the bottom instead of the top. The code is very similar except for the fact that we reduce the scale by 1.4.

  // Avatar -----------

leave avatarScaleFactor = (min (offset_HeaderStop, offset)) / avatarImage.bounds.height / 1.4 // Lower the animation
la avatarSizeVariation = ((avatarImage.bounds.height * (1.0 + avatarScaleFactor)) - avatarImage.bounds.height) / 2.0
avatarTransform = CATransform3DTranslate (avatarTransform, 0, avatarSizeVariation, 0)
avatarTransform = CATransform3DScale (avatarTransform, 1.0 - avatarScaleFactor, 1.0 - avatarScaleFactor, 0)

As you can see, we use my function to stop Avatar scaling when the Header transformation stops (offset_HeaderStop).

At this point we define which one is the foremost team depending on the current shift. Until displacement is less than or equal to offset_HeaderStop, the top layer is Avatar; higher than offset_HeaderStop it's header.

  whose offset <= offset_HeaderStop {

whose avatarImage.layer.zPosition < header.layer.zPosition{
                    header.layer.zPosition = 0
                }

            }else {
                if avatarImage.layer.zPosition > = header.layer.zPosition {
header.layer.zPosition = 2
}
}

White Label

Here is the code to animate the white label:

  let labelTransform = CATransform3DMakeTranslation (0, max (-distance_W_LabelHeader, offset_B_LabelHeader - offset)
headerLabel.layer.transform = labelTransform

Here we present two new shame-to-mig variables: When displacement is equal to offset_B_LabelHeader, the black username will touch the bottom of the heading.

distance_W_LabelHeader is the distance required between the bottom of the header and the white label to center the label inside the header.

The transformation is calculated using this logic: The white label must be displayed as soon as the black label touches the header and stops when it reaches the center of the header. So we make the Y transition using:

  max (-distance_W_LabelHeader, offset_B_LabelHeader offset)

Blur

The last effect is the blurry headline. It took me three different libraries to find the right solution … I've also tried to build my super simple OpenGL ES help. But updating the blur in real time always ended up being extremely laggy.

Then I realized that I could calculate blur only once, overlap the blurry and blurred picture and just play with alpha value. I'm pretty sure that's what Twitter devs did.

In viewDidAppear we calculate the blurry headline and we hide it and put alpha to 0:

  // Header - Blurred picture

headerBlurImageView = UIImageView (frame: header.bounds)
headerBlurImageView? .image = UIImage (named: "header_bg")?. blurredImage (withRadius: 10, iterations: 20, tintColor: UIColor.clear)
headerBlurImageView? .contentMode = UIViewContentMode.scaleAspectFill
headerBlurImageView? .alpha = 0.0
header.insertSubview (headerBlurImageView, underSubview: headerLabel)

The blurred view is achieved using FXBlurView.

In the scrollViewDidScroll function, we only update alpha based on offset:

  headerBlurImageView? .Alpha = min (1.0, (offset offset_B_LabelHeader) / distance_W_LabelHeader)

The logic behind this calculation is that the maximum value must be 1, the blur must start when the Black Label reaches the header and it must stop when the white label is in its final position.

That's it!

I hope you've had this tutorial (despite the shame-on-me variables : P ). Studying how to reproduce such a good animation was a lot of fun for me.

And poke me on Twitter if you have any interesting UIs you want to see x-ray and rebuilt: we could work with it!  :)

A big thank you goes to Nicola who has taken the time to review this article!

Download source




Source link