SwiftUI Hackathon
During WWDC 2019 Apple presented a set of new tools for developers which was as unexpected as the snow in winter. One of the most important tools worth mentioning was, of course, SwiftUI, a new framework that allows you to implement app interface in a declarative style. It’s been much talked and written about with thousands of questions already there on Stack Overflow. 3–4 days after the event the infosphere was flooded with video tutorials, books and what not 😲.
Honestly, we couldn’t let us stay on the sidelines either and produced a couple of post-event reviews and posts. But staying complacent is not about us, so we also decided to test-drive something substantial without using well-working and obvious examples.
Hackathon turned out to be the best possible solution to get first-hand experience and share it with a safe conscience thereafter. As you understand the main topic we chose was SwiftUI. We thought it would be cool to have a feel of the declarative style from Apple that even applies to complex concepts like animation.
Tasks
We decided that we would develop one app to produce something runnable within one working day. Displaying a list of images which is a frequently used case in many projects. We started the day with defining the tasks and reading SwiftUI documentation available 😐.
The features we tried to implement:
- View with a search bar. Namely: background, paddings, icon, clear and cancel buttons appearing with animation.
- A list of asynchronously loaded images with the background of the required colour and the author’s name at the bottom of the cell.
- A Detail Screen with the picture, with a custom back button, downloading of image to the device, the name of the author and picture sharing.
- An Onboarding screen with some interesting animation.
Implementation
We tried to only use SwiftUI tools without wrapping UIKit elements. Lots of things within this framework work differently, at least not the way we got used to. SwiftUI is based on new layout elements, the state of which can be changed using property wrappers.
NavigationView
Adding NavigationView we get NavigationBar and can easily add a title to it. Transition to another screen is also there out of the box — by using only one NavigationButton. To display details onscreen we should pass the view to it.
SearchBar
SearchBar was created in a separate view. HStack, which contains two views, is in the main view. The first one is the container with the TextField itself, the background, the icon and the Clear button. The second one is the Cancel button which appears with animation when you start to edit the text.
List
The next is the List with images. We send over the set of models to it and based on the model ImageRowView is created. There is an image in ImageRowView, down in the middle there is the text and the background underlay under the image with a certain colour. Each of the items gets to the List and is displayed in the standard way. Very simple. (We used our own Asynchronous image download service).
Detail screen
By clicking on each image, NavigationView will send us to the preview screen. On this screen there is a full-screen image, at the bottom of the image there is a container with the name of the author of the image, the button to download the image to the device and the button to share the image. Pictures in the buttons used the SF system symbols.
Onboarding screen
We planned to implement text and icon animation on this screen but did not have enough time for that during the hackathon.
Issues
We had to face lots of issues! Let’s list the most prominent ones:
- The code which is not that readable. You can see it in the above-given examples (even though they were pretty simple). A small container with even 2 views inside can not be read easily. Less than 20 lines of code but it’s difficult to make ends meet.
- Navigation is the issue. Standard NavigationView works well, but if you decide to customize it, it turns out to be not so easy. SwiftUI does not allow to apply dismiss to your own button 🤷♂️.
- Lots of constraints of SwiftUI itself. We can enumerate a number of things. There is no CollectionView implemented, one can neither hide the keyboard nor prevent it from showing right at the TextField. You can’t change the keyboard button type and so on. It can actually be implemented: you can wrap the UIKit elements to be used within SwiftUI.
You can hide the keyboard at the Text Field in the following way:
import SwiftUIextension View {
func endEditing(_ force: Bool) {
UIApplication.shared.keyWindow?.endEditing(force)
}
}
If you want the image to be resized to be displayed in a wide screen mode as well as have its height proportionally set, it will not be possible within SwiftUI. Image does not store the image size. For this you should create UIImage and apply aspectRatio to Image to pass the sizes to it from UIImage 😔.
Despite those complications and immaturity of the current version of SwiftUI, by the end of the hackathon we managed to develop an app version which could complete its own task, pilot-tested the framework itself and can now share our experience with a wider audience.
SwiftUI is an interesting and high-potential framework. The current beta is applicable for smaller apps and demos but can hardly be used within large-scale projects with apps to be deployed into production.