Better Programming

Advice for programmers.

Follow publication

A Direct Comparison Between UIKit and SwiftUI by Building the Same App

Seb Whitfield
Better Programming
Published in
5 min readMay 11, 2022
Photo by Maxwell Nelson on Unsplash

I’ll be honest. I didn’t want to like SwiftUI… but I do. Since the launch of SwiftUI in late 2019 I have been adamant I wasn’t going to use it and I would stick solely with UIKit.

Whilst it is still required for some things to have to fall back on the use of UIKit, SwiftUI has this magic way of making it easy to create UI elements that could be a head-scratcher in UIKit.

Swift as a language has given the team over at Apple time to reflect on what iOS Developers are doing often and the problems that UIKit has faced.

Do you want to do something simple like add padding to a label or an image inside a custom button with text? Sure…!

You could subclass a UILabel and initialize it with some kind of UIEdgeInsets, or you might add override functions or properties for your subclass such as intrinsicContentSize: CGSize.

There are many valid solutions out there but a big wow factor with SwiftUI is ViewModifiers.

Having played around a little with SwiftUI over the last few days I’ve really seen the attraction to this new development of Swift.

I wrote an article a few weeks back with a solution to fixing my little “Image in a UITextField” problem and decided to give it a go in SwiftUI!

I’m sure many of you reading this will see this as trivial in SwiftUI.

This article is not aimed at people who are currently learning/know SwiftUI. Instead, this is to show an example of something I’d previously created in UIKit for those looking for a somewhat direct comparison.

The first result

A simple TextField with an image wrapped in a HStack using SwiftUI

The code below is what’s used for the above GIF. This is a very simple example.

I have wrapped it in a NavigationView (UINavigationController for solely UIKit users out there) and thrown it in a Form which appears to be the equivalent of a UITableView.

It looks a little repetitive though, right? I almost can’t believe I’m typing that. We’ve already saved on many a line of code configuring our UITableView, UINavigationController/UICollectionView, NSLayoutConstraint, UITableViewDelegate, UITableViewDataSource… not forgetting the custom UITextField on top!

A little refactoring

If we press the cmd key and click on the HStack, we can then select to extract this section of code into its own subview:

Swift will then kindly name this ExtractedView() for us until we find an appropriate name for it and place it below out ContentView().

I’m going to rename this PersonalInfoStack and add 3 new properties for our image and textField.

This returns “some kind of View”, in this example it will return a HStack with an image and a textField. We then pass the properties through the new constructor when we call an instance of PersonalInfoStack():

Modifiers being used in this Subview will be applied to every instance, so be careful which you use. You can always add separate modifiers for a specific View as you will see below.

Because we are using an @State property on our new subview, we need to use the @Binding keyword here on our textFieldText: String property to tell Swift, “Hey, I’m going to use a value here but I want it to be the same as what I’m passing in… If I update here, update it where it is originally declared”.

Now for the reveal of the newly refactored ContentView:

Okay, getting there.

This looks small now. Ridiculously small actually for what we actually have in our UI. We don’t want to go overboard, but let's imagine that you have more views in here and a lot of Logic.

What we don’t want to achieve is an MVC issue where the code becomes unreadable/hard to manage!

You could choose to refactor the Section, but be wary; there is a fine line between abstraction for the sake of sanity, and abstraction that’s so abstract, you can’t understand what’s going on!

Personally, I like to keep certain parts of code as they are in order to improve readability such as deciding not to refactor the Section.

When actually coding, I often use alt + cmd +< or alt + cmd + > to collapse and open code. It’s definitely a welcomed small helper for a longer ContentView():

Move your cursor to the inside of the curly braces and use the shortcut above. Code will be collapsed within the scope of the curly braces as shown.

Moving on!

The final example will be a TextField that shows and hides the text to match my previous article. An example of this would be for some kind of password or secure entry.

In UIKit we would set the textField.isSecureTextEntry property to = true. In SwiftUI we can write the following:

As you can see above, we have added a Boolean that determines if the password is visible or not.

This Boolean value also determines what type of image is being used for the Image via a ternary operator:

Did you spot the .Padding(.trailing) ViewModifier we added to the Text?! Just one line and we now have a little padding exactly where we want it!

This is not a dump on UIKit!

I actually hit an interesting hitch when attempting to change the background color of a Form in SwiftUI and found fairly quickly that I had to fall back on UIKit. I was expecting that I could add a Color modifier on the Form.

After that didn’t work I tried wrapping it in a ZStack which also didn’t work. Some research later I discovered the following solution for those who may find it useful:

This isn’t the best color choice here, but it is an example of needing to switch up the framework and implement UIKit when necessary.

My use of UIKit will still be present but just from this small example and my comparison of implementing the same things in both UIKit and SwiftUI, it is safe to say that SwiftUI will be something I am keen to learn more about!

Thanks for reading.

No responses yet

Write a response