返回首页

SwiftUI Series 07|Conversion of thinking from UIKit to SwiftUI

What’s really hard is letting go of the default habit of “I’ll drive the interface manually”

Many UIKit developers switch to SwiftUI for the first time. The most painful part is not always that they feel:

  • The API is obviously not complicated
  • But why is it always difficult to write?

The reason is often that the underlying thinking model has not been cut through yet.

Because UIKit is asking by default:

  • Which view do I want to create now?
  • When will I update it?
  • How do I manually keep it consistent with the data

SwiftUI is more like asking:

  • What is the current status
  • What should the interface look like in this state?
  • How the interface should naturally reorganize when the state changes

These two ideas are that the position of control has changed.

1. The first thing to put down is “I mainly rely on my manual driver for interface updates”

Many experiences in UIKit revolve around this:

  • When to reload
  • When to setNeedsLayout
  • Which callback to change a certain subview?

SwiftUI certainly needs to manage state, but what it wants to do is:

  • Manage status sources
  • Manage state boundaries
  • How management status is mapped to UI

Instead of continuing to focus on “how do I refresh the interface manually?”

If this habit is not changed, the most likely situation to occur later is:

  • SwiftUI seems to be written in a declarative way
  • But I still have the imperative driver of UIKit in mind

In the end, the code will become a mixture of two kinds of thinking, neither taking advantage of SwiftUI nor losing the clear sense of control of UIKit.

2. The second thing to put down is to treat View as a stable object.

This is the habit that developers with a UIKit background are most likely to bring in by default.

In UIKit, it is natural to think of a page or cell as:

  • a created object
  • Will be updated continuously in the future

But SwiftUI’s View is more like a state description. It is not “an object that I have been working on changing for a long time”, but more like “the structural expression of the interface in its current state”.

This means that if you always start from “This View will always be there, I just keep changing it”, it will be easy to:

  • Life cycle judgment
  • Status storage location
  • Asynchronous task binding

Frequent pitfalls on these issues.

3. The third thing to let go of is over-reliance on local patches to repair the UI.

A very common path in UIKit development is:

  • First put the view out
  • Correct whatever is wrong
  • If a control is a little off, patch it locally.

This method is not completely unusable in SwiftUI, but if you keep doing this, the page will easily become:

  • There are a lot of modifiers
  • Unclear structural hierarchy
  • One minor repair leads to another layout change

Because SwiftUI encourages expressing the structure clearly first, and then attaching local modifications to it. If the structure itself is unstable, local patches will repair the problem and break it into pieces.

4. The fourth thing to change is: think less in terms of “controls” and more in terms of “state flow”

In UIKit thinking, many page organizations are control-centric:

-What does this label show?

  • Whether this button is disabled
  • When will this tableView be reloaded?

SwiftUI encourages starting from the state flow:

  • What is the current status of the page?
  • Which UI fragments should be mapped to this state
  • How the state evolves after an action

This change is critical because it directly affects:

  • How to design ViewModel
  • How to disassemble components
  • How to determine which status should be shared and which should not be shared

5. The fifth thing to change is: don’t rush to translate all UIKit experience into SwiftUI corresponding writing method

When I first learned this content about SwiftUI, I would subconsciously ask this question:

  • What is this equivalent to in UIKit?
  • Which callback corresponds to this life cycle
  • Is this behavior equivalent to reloadData?

This type of mapping is helpful when getting started, but it can cause a problem if relied on long-term:

  • Always looking for a UIKit counterpart
  • But didn’t really accept that SwiftUI is another way of organizing

The turning point that is really easy to use is usually:

I started thinking about pages directly in SwiftUI’s problem-awareness, rather than translating back to UIKit first and then making decisions.

6. A more practical transition method: Don’t pursue “complete brain change immediately”, first change the way you ask a few high-frequency questions.

The most helpful thing is to first change the way you ask these questions:

Put:

  • When do I refresh this view?

Change to:

  • What state changes should drive this area update

Put:

  • When should this control be changed?

Change to:

  • Who should own this value?

Put:

  • Does this page appear once or multiple times?

Change to:

  • What state or life cycle should this task be bound to?

The change in this way of asking may seem small, but it will slowly pull the default thinking toward SwiftUI.

7. Conclusion: The most important thing when moving from UIKit to SwiftUI is to reposition the thinking of control.

To put it in shorter form, I would say:

From UIKit to SwiftUI, what really needs to change is from “I will manually drive the interface” to “I will define the state and boundaries, and let the interface be established according to the state.”

Once this starts to happen, many things that originally felt like “Why is SwiftUI so awkward?” will slowly become natural.

FAQ

读完之后,下一步看什么

如果还想继续了解,可以从下面几个方向接着读。

Related

继续阅读

这里整理了同分类、同标签或同类问题的文章。