loading...
Cover image for How to make a "swoosh-in" title

How to make a "swoosh-in" title

guseulalio profile image Gus Eulalio ・4 min read

N.A.:
For the lack of a better word, I'm using swoosh-in.
Let me know in the comments if there is a better verb to use.

Here's a nice little trick to add some pizzazz to your app's title. We'll have the title appear in a swoosh effect from left to right.

What we're going to do here:

  • We'll create a custom view to encapsulate the whole thing.
  • We'll make the view's background transparent.
  • We'll need a label and will use as a mask to our view.
  • We'll add a new view to the above one and place it outside of the view's bounds.
  • We'll animate the view into the visible area.

First we create the view:

class SwooshInTitle: UIView
{
    init(title: UILabel, frame: CGRect)
    {
        super.init(frame: frame)
        backgroundColor = .clear
    {

    required init?(coder: NSCoder)
    { fatalError("init(coder:) has not been implemented") }
}

This creates the view and sets its background color to clear, which is to say it will be transparent for now. (Note that the second initializer is needed and if you don't add it in, the compiler will complain)

Also, the initializer receives a UILabel as the title (which is the text that is going to be shown), and the frame where the title will appear.

Still in the initializer, we'll set the title as the mask to our view. This will make the view's borders follow the shape of the text. So anything in the view that is out of the text's borders will be cropped out.

Add the following right after the backgroundColor line in the initializer:

        title.frame = frame
        mask = title

Now we need to make the part that will be made visible in the view. All we need is a simple block of non-transparent content. It may be an image with a specific color pattern or something as simple as another view.

For the sake of simplicity, we'll use the former. We'll need this view to be accessible outside the initializer, so we'll make it a property of our view:

class SwooshInTitle: UIView
{
    private var blockView: UIView?
...

Then add the following code to the end of the initializer:

        blockView = UIView()
        blockView?.backgroundColor = .blue

        addSubview(blockView!)

Notice that the block view's background color is set to blue, so it isn't a transparent view. This is the view that you can replace with an image (UIImageView) if you want something fancier.

Also note that we didn't place the view anywhere in our view yet, i.e., we didn't give it a frame. We can do it here in the initializer, but it isn't necessary right now, it isn't supposed to be visible anyway.

Now we have all we need. We just need the animation now. We'll have a method to do that so you can perform the animation anytime you want, instead of having if done as soon as the view is shown.

Create the following method:

    func swoosh()
    {
        blockView!.frame = CGRect(x: -frame.width, y: 0, width: frame.width, height: frame.height)
        UIView.animate(withDuration: 1)
        {
            self.blockView?.frame.origin = CGPoint(x: 0, y: 0)
        }
    }

The first thing we do in the function is to place the the block view just outside and to the left of our view's frame. Notice that we set the width of the block to be the same as our view's, and the x position to be -frame.width.

Then we initiate the animation block with the duration of 1 second (adjust the time according to your preference). Whatever is inside this closure will be the final state after the animation. We want the block to cover our view completely. It already has the same size, so all we need to do is to place it at the (x: 0, y:0) position.

And that's it, the animation is done. Remember that our view has a label as mask, so when the block is pushed in, it will appear in the shape of the text.

Now let's use the class above in code and make the magic happen.

class ViewController: UIViewController
{
    var logo: SwooshInTitle?

    override func viewDidLoad()
    {
        super.viewDidLoad()
        view.backgroundColor = .white
    }
}

Suppose this is your view controller. You'll need to have a property for the SwooshInView.

Now we need to create our label. Add the following to the end of the viewDidLoad method:

        let title = UILabel()
        title.text = "Abracadabra"
        title.font = UIFont(name: "Zapfino", size: 72)
        title.textAlignment = .center

Just run-of-the-mill label configuration, nothing special here.

Now we'll create the SwooshInView object. Add the following to the end of the method:

        logo = SwooshInTitle(title: title, frame: view.frame)
        view.addSubview(logo!)

Here we're giving it the frame of the whole screen. It doesn't need to be that way, I'm just being lazy. Give it enough room for the text to appear fully, that's all.

Now we'll add a button to trigger the animation:

        let button = UIButton()
        button.setTitle("Abracadabra", for: .normal)
        button.setTitleColor(.blue, for: .normal)
        button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
        view.addSubview(button)
        button.frame = CGRect(x: 10, y: 10, width: 200, height: 40)

As soon as you add this, the compiler will complain about the #selector thing. We need to add a function to this class:

    @objc private func buttonClicked()
    {
        logo?.swoosh()
    }

That's it. You click the button, and the title will be animated onto the screen.

Other suggestions

As mentioned above, you can use an image as the block. I'll leave it to the reader to do this as a challenge. I did it here and it worked great.

Another option is to add a gradient background to the block. I'll leave that as a challenge too.

If you've gotten this far, thank you for reading this. Leave a comment if you will. Suggestions and criticism are welcome.

Discussion

pic
Editor guide