Bring Your Titles to Life in iOS
Develop a text label that has a video as a background.
We will be developing this in Swift using CoreText and AVKit.
What will we be doing?
AVKit uses an AVPlayerLayer
instance to display video in a view. AVPlayerLayer
is a subclass of CALayer
. In UIKit all views are backed by a CALayer
instance. CALayer
has a mask property, according to Apple's developer documentation, this is what it does:
An optional layer whose alpha channel is used to mask the layer’s content.
We will create an image from a string using CoreText, with the rest of the image filled with the UIColor.clear
, and use it as the the AVPlayerLayer
's mask.
VideoLabel.swift
Create a new Xcode project, using the iOS Single View Application template. Call it VideoLabelDemo. In the next screen, make sure to select Storyboard in the drop down menu titled User Interface.
We will be using UIKit for VideoLabel
. Create a new Custom Touch Class source file.
Call it VideoLabel and make it a subclass of UIView
.
Using the label should be as easy as possible, hence we will create 2 initializers that allows us to plugin the values and off it goes.
Now that we have all we need, let’s layout our view.
setupBackgroundVideoIfNeeded()
will create our video player that will play in a loop in the background. updateVideoMask()
will create the text mask and update its dimensions when the view changes any of its dimensions.
setupBackgroundVideoIfNeeded()
The definition of the this method looks like this:
We only want to initialize the player layer once, therefore we will check if the property playerLayer
has been set up or not. AVPlayerLayer
presents the video but it needs an AVPlayer
to present. We setup an AVPlayer
instance with the URL
provided when initializing the view. We also add an observer to the player, that will inform us when playback has ended so that we can loop the video by rewinding and playing again.
Once our player is setup, we can create an AVPlayerLayer
, add it to our view's layer hierarchy and start playback.
updateVideoMask()
The definition of this method looks like this:
We create an attributed text from the text
property provided at initilization, if the view was initilized with attributedText
we will modifiy it's font size to take into consideration the OS's Dynamic Text settings, making our label respect Accessiblity's Larger Text settings values. We also set the accessibilityFrame
to match our text’s bounding box, the accessibilityFrame
should be in screen coordinates, we transform our text box, from the bitmap's space, to view space then to screen space.
The attributed text is used to draw a string in a graphics context using CoreText. An image is created from the graphics context and returned to the calling function.
Accessibility
Our label supports Dynamic Text and has set it’s accessibilityFrame
, we will need to provide more information to properly support VoiceOver. Add the following method to the view:
This will set our text as the accessiblity label and tell VoiceOver that to treat us as static text. Call it in the updateVideoMask()
method.
How to use VideoLabel
You can import the project using Swift Pacakage manager, or you can drag the VideoLabel.swift file into your Xcode project. Then use one of the initializer described above.
Finally, you can use multiple labels in your view with different videos, you are not limited to one video at a time.
I hope you enjoyed the tutorial and thank you for reading.