The lifecycle of a SwiftUI view.

Tram Ho

  • One of the things that distinguishes SwiftUI from its predecessors like UIKit and AppKit is that the view are primarily declared as value type like struct instead of class .
  • This is one of the changes in the architectural design that makes the SwiftUI API light and flexible. This change sometimes makes developer including me often confused because of the knowledge of object oriented programming has been used before.
  • So in this article, let’s take the time to carefully study the meaning and usage of SwiftUI in declaring, interacting with the UI and moreover finding ways to have can find new methods better than using UIKit , AppKit in new projects.

1 / The role of the property body:

  • Property body in View Protocol is probably the most confusing thing in SwiftUI especially when it is closely related to view update as well as rendering cycle .
  • In UIKit , AppKit we use method like viewDidLoad or layoutSubviews to recognize system events as well as process logic while with SwiftUI body property we can render the view without using the above method .
  • body property allows us to render view based on its current state and the system will rely on its current state to see if it is necessary to re- render the view. For example, when building a UIKit ViewController we often trigger model update with the viewWillAppear method to ensure that the viewController always render the view with the latest data :

  • When we switch to S wiftUI thay vì ý tưởng rendering lại view lại mỗi khi viewWillAppear thì chúng ta triển khai việc viewModel that sẽ update khi xử lý latest body property`:

  • However, the problem with the above implementation is that the view body will be compared as soon as the viewModel changes which means we will cause a lot of unnecessary model update .
  • It is easy to see that the body property not a convenient place to handle these unnecessary update but instead SwiftUI provides some similar features as in UIKit , AppKit . We are talking about the onAppear customization similar to the viewWillAppear in controlelr :

2 / The initializer problem:

  • Life cycle is an important issue that every developer should keep in mind when working with view . In fact, it is easy to see that the view in SwiftUI do not have a proper life cycle because we use the value type and not the reference type .
  • When we want to change a ArticleView and viewModel update whenever the app is resume when moved to background instead of every time viewappear . One way we do that is to track each object through the NotificationCenter on initialization as follows:

  • The above implementation works normally until we get the ArticleView into other view . To express this case we create many ArticleView value like ArticleListView by using List and NavigationLink :

  • NavigationLink will ask us to provide destination details for each incoming view and we have setup in NotificationCenter when creating ArticleView . The observation will be immediately active even though the view are not yet render .
  • Therefore we should implement the function as small as possible and the ArticleView will be updated when the app is moved back to the foreground instead of update each ArticleViewModel one by one.
  • To implement the above implementation we need onReceive instead of using NotificationCenter to track the view initialization. Plus we no longer need Combine cancellable :

  • When SwiftUI view is initialized, it does not mean it will be displayed or used. That’s why SwiftUI requires us to first create view instead of instantiating them one by one.

3 / Ensuring that UIKit and AppKit views can be properly reused:

  • We can put UIKit , AppKit to use with SwiftUI through Protocol UIViewPresentable and we will be responsible for creating and update instance of view being displayed and used.
  • To illustrate, let’s render NSAttributedString using a UIKit instance like UILabel :

  • However, to use the above implementation we need to solve two major problems
    • In case we initialize UILabel by assign it to the property means that we can not re-initialize klaij it whenever struct is initialized again.
    • Do not update the view with updateUIView method , label will continue render attributedText like old and assign for makeUIView although the string has been update .
  • makeUIView not create UILabel with the makeUIView method. We always assign the label string with the attributedText updateUIView property every time the updateUIView is called:

  • With the above method, finally our UILabel can be reused and attributedText is always update with the wrapper string property .
Share the news now

Source : Viblo