Skip to content
vrhermit

vrhermit

Code & Writing by Joseph Simpson

  • Canvatorium
  • Technical
  • Professional
  • Personal
vrhermit
vrhermit
Code & Writing by Joseph Simpson
Retrospective | Technical

SwiftUI – A note about onAppear()

ByJoseph November 3, 2019June 25, 2023
SwiftUI

This morning I made a custom version of a picker for the events form. I needed a way for events to select a different timeline. The default picker in SwiftUI had some limitations so I set out to make my own. The only main difference is that it uses a sectioned list with timelines sorted into non-archived and archived sections. I made a binding variable to pass in the selected timeline. This allowed me to update the selected timeline from the picker view, then just close it when done.

struct TimelinePicker: View {

    @Binding var selectedTimeline: Timeline?
    @ObservedObject var dataSource = RADDataSource<Timeline>()
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body : some View {
        List {

            ForEach(dataSource.loadSectionedDataSource(sort: self.getSort(), predicate: nil, sectionKeyPathName: "isArchived"), id: \.name) { listSection in

                Section(header:

                    HStack {
                        Text(listSection.name == "1" ? "Archived Timelines" : "Timelines")
                    }
                    .font(.system(.headline, design: .rounded))

                ) {
                     ForEach(self.dataSource.objects(inSection: listSection)) { timeline in
                        
                        Button(action: ({
                            self.selectedTimeline = timeline
                            self.presentationMode.wrappedValue.dismiss()
                        })) {
                            
                            HStack {
                                TimelineListRowView(timeline: timeline)
                                .foregroundColor(.primary)
                                Spacer()
                                if(self.selectedTimeline == timeline) {
                                    Image(systemName: "checkmark")
                                }
                            }
                            
                        }
                    }
                }
            }
        }
    }

    public func getSort() -> [NSSortDescriptor] {
        ...
    }
}

It just would not work though. I tried several ways of passing in the timeline, binding, observed object, environment object, etc. Nothing would work. Every time I closed the picker the initial value remained set on the events form.

Turns out that’s because I’m an idiot. I was using a call to onAppear to load data from the event record into a View Model class. This was running every time I closed the timeline picker. I would set the initial value, go to the picker, select a new value, and then close the picker which would call onAppear to set the initial value again.

The fix for this was super simple. I just added a new state variable called onAppearCalled and initialized it to false. Then I could check this condition in the function that populates my form when onAppear is called, setting it to true when it is called.

func populateOnAppear() {
    if(self.onAppearCalled == false) {
        ...
        self.onAppearCalled = true
    }
}

My Timeline Picker

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Tumblr (Opens in new window) Tumblr
  • More
  • Click to print (Opens in new window) Print
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to share on Pinterest (Opens in new window) Pinterest
  • Click to share on Telegram (Opens in new window) Telegram
  • Click to share on WhatsApp (Opens in new window) WhatsApp

Like this:

Like Loading...
Post Tags: #SwiftUI
Next: User Interface Update
Previous: Setting up CloudKit with Core Data

Get my articles in your email

Join 22 other subscribers

A-Frame AI AppUpdate AR BabylonJS Books Career ChatGPT CloudKit CoreData FileMaker Food Gaming Kadence MixedReality parody PlayCanvas Podcast SpatialComputing SwiftUI Thoughts visionOS VisionPro VR VueJS WebXR WordPress

Work with Me

Ready to streamline your workflows and enhance your digital presence?

Do you want to take your first step into Spatial Computing?

Discover how Radical Application Development can help transform your business.

Get in touch or learn more at radicalappdev.com

Mastodon Mastodon
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Privacy Policy

Follow my work

Github Linkedin YouTube

© 2025 Joseph Simpson | Radical Application Development

  • Canvatorium
  • Technical
  • Professional
  • Personal
 

Loading Comments...
 

    Search
    %d