Latest posts

One week with SwiftUI

I just wrapped up a week of working with SwiftUI full time. It certainly has some rough edges and each new beta version brings a lot of changes. Here is a recap of what’s working for me and what I still need to figure out.

List views are really simple in SwiftUI. The first layout that loads in my app is a List view has two main sections. The first section has a few rows for some saved queries that I’ll implement later, the second section is dynamic data from Core Data. Xcode Beta 5 introduced some new property wrappers and environment variables for working with Core Data. You can read more about these additions here.

Data entry: I made some simple forms with a few fields and a custom control for picking colors. The only problem I’m having with data entry is actually with the modal presentation implementation of SwiftUI. I call the sheet modifier and pass it a view, but this has some issues with not loading data on repeated calls. I’m calling this modal sheet from the main list view for adding new records, and from a detail view for editing existing records. I have an issue where I can’t get the list view to update when I modify a record that is a few views away (List > Detail > Edit). I think this has something do do with the way that I’m loading the list with Core Data records, as there is nothing that is triggering a refresh when I save the modified record. I need to figure out a better way to setup a publisher with Core Data. A possible workaround for this is to implement record editing on the list rows, just like when a user swipes a table row to disclose an edit button. I just can’t seem to figure out how to do that yet. I may use the new ContextMenu instead if I can’t figure it out soon.

Button("Add List") {
    self.editModal = true
}
.padding(EdgeInsets(top: 0, leading: 0, bottom: 10, trailing: 20))
.accentColor(Color(Theme.shared.appMainTint))
                          
.sheet(isPresented: $editModal,
       onDismiss: {
        self.timelineEditModal = false
},
       content: {
        ListEditView()
            .environment(\.managedObjectContext, self.managedObjectContext)
})

Color Picker: The list based item in my app is composed of of a name, color, and icon. I wanted to try to mimic the new color picker in the new version of the Reminders app. While SwiftUI doesn’t have an alternative to the Collection View yet, I was able to get my color picker working by dynamically calculating a number of columns. I used Geometry Reader to get the width of the parent view, then just divided it by the size (including padding) that I wanted each color to take up. I passed that number to a child view that parses out a list of colors into rows and columns. I got the idea for the grid here. I’m planning on implementing something similar with the icon, using a subset of SF Symbols.

Dynamically sized color picker on iPad and iPhone.

I spent a large part of today refactoring a lot of my code into smaller views that are easier to reason about. Xcode can have a hard time handling complex views with lots of embedded views, so it can be helpful to break them into small components where possible.

Some issues I haven’t figured out:

  1. Master Detail by default – On iPad I get free Master Detail by default, but I’m not certain this is right for my app. I have not found a way to just fill the screen with my list view. There is also an annoying issue that iOS loads an empty detail view when in portrait mode. I can’t believe this is still the default behavior after years of iOS but it is… 
  2. Modal views seem to break when loaded from a List item. They will work correctly the first time, but when opened two or more times they do not load the data that is being passed to them. I was able to confirm that the data is being passed, but SwiftUI is not using it to update the views.
  3. iOS 13 has a new (old) style for rounding the corners of grouped tables/lists. I can’t find a way to do this yet. .listStyle(GroupedListStyle()) does not do the trick.
  4. List Edit Mode – I can toggle edit mode on, but have yet to figure out what to do next. I want to let users reorder rows, and I want to show an info button that will open a modal sheet for modifying a record.

SwiftUI is still new and can be frustrating at times but I think I can safely say that I’m going to make the production version of my app with it. In one week of work I caught up to the UIKit version of my app, which took nearly two months. Granted, a lot of that time was focused on planning and design, which benefited both versions. I think I’ll stick with SwiftUI just so I never have to deal with Auto Layout ever again.

Thinking about SwiftUI

Last week I decided to spend the weekend learning about SwiftUI. The weekend turned into an entire week but I was eventually able to learn everything I set out to learn. This course on Udemy was particularly helpful.

I’m going to take a long weekend to give myself time to reflect on what I have learned so far. One thing I want to think about is if I should use SwiftUI for my app. The app I’m working on is simple enough and SwiftUI can do almost everything I need. There are a few areas where I may have to drop out to UIKit but for the most part I think I can make it work. Importantly, I think I may be able to make a better user experience with SwiftUI than I can with UIKit. So many things in UIKit require more code and complexity and if I stay on that route it may be several months before my app meets the expectations that I have for it.

I guess I have a lot to think about this weekend.

Questions for myself about SwiftUI

This weekend I’m going to spend some time with SwiftUI. I tried to think of the most important questions that I want to answer. I have no idea how much progress I will make but if I come up with answers to these I’ll write about them.

  1. Can I connect a SwiftUI List to a Core Data FetchedResultsController?
    1. How do I set this up?
    2. Load data
    3. Edit data
    4. Delete data
  2. Does SwiftUI support advanced table features?
    1. Readable Size for cells
    2. Reorder controls
    3. Context actions
  3. How can I pass an object from a list view to a form view?
    1. Dependency injection?
  4. Can I make form views that do not save data until the done button is tapped? Pass back to the List view to save the changes. 
  5. Can I easily segue to UIKIT View Controllers? I need access to CollectionViews and Large TextViews, neither of which exist in SwiftUI.