Creating custom control in Swift
I spent last two evenings working on my app’s main screen. Again, Xcode was driving me crazy with random bugs that efficiently slowed me down ;) I needed to add an action by ctrl dragging element from storyboard to ViewController class. As I already mentioned, performing drag and drop with control pressed on my touchpad is a challange: four fingers involved ;). When you’re successful with placing dragged element in the desired position, a popup window appears and you have to make three adjustments: change connection type, enter action’s name and change object type. Only to discover that: Could not insert new action connection: Could not find any information for the class named ViewController.
This is a bug. ViewController class exists in my project. Following this stackoverflow question I tried:
- cleaning the project,
- cleaning and running the project,
- quitting Xcode,
- removing and readding the file.
What actually did the trick was adding a few enters to ViewController class ;) And of course every time I repeated drag and drop operation I had to fill in the data in the popup window again.. I used a lot of swear words to help me get through it :)
Getting back to the point.. I decided I needed a separate user control for displaying morning and evening magic hours. I followed this tutorial and my screen looks now like this:
There’s settings icon in the top left corner and two user controls displaying morning and evening golden hours. Arrow icon indicates sunrise / sunset time.
My user control class is basically a class deriving from UIStackView, a container control that can arrange elements in horizontal or vertical order:
@IBDesignable class GoldenHoursControl: UIStackView
The @IBDesignable declaration lets Interface Builder instantiate and draw a copy of my custom control directly in the canvas, it’s like a live preview in the designer. In order to use my custom control in the story board, I have to place regular UIStackView control and connect it with my custom class in the „Identity inspector” tab.
What I don’t like with this approach is that I have to create all ui elements manually from code and place them in main container.
Custom control can expose properties that can be accessed directly from designer. In order to enable it, property has to be marked @IBInspectable. Unfortunately not all types are supported, I wanted to distinguish between morning and evening (to set different icon) and tried with enum in the first attempt. Didn’t work, had to change to string.
@IBInspectable var time:String = "morning"
My control exposes four designer properties: a string „morning” / „evening” for setting proper icon and three strings for setting golden hour, blue hour and sunrise / sunset time. I am able to set the values directly in designer, which is pretty cool.
I had some difficulties with proper positioning of elements in the canvas. I don’t still fully understand how the constraints work, it’s more trial and error method for me right now. I will have to deal with this in the future ;)
More code? Check out my github project.