Skip to main content

Quick Glimpse

Why are we good?

Yes. Everybody who was trying Defined Elements of SwiftUI had this question. Even though you are recommended to here by a friend or a colleague, you should still get a glimpse of what Defined Elements is and what Defined Elements can offer.

The answer is very simple –– we are doing something that pure SwiftUI cannot do, like:

  • Do the routing to everywhere by a nice short function call. Including proceed to a child page, jump to another stack, swap the current view, back to the previous page, and more.
  • Set a status bar style per page! And change the status bar style by simply flipping an @State variable.
  • A bag of handy components for building a simple, yet user-friendly, UI.
  • A super handy CoreTab to replace the traditional TabView, which has a lot of restrictions.
  • Global font and color configuration.

Issues of SwiftUI Navigation

In pure SwiftUI, you are required to use NavigationView and NavigationLink to navigate between views. It is not a very big deal, but when you want to go back from the second view to the first view, you have to either change the @State variable in the first view or use SwiftUI presentationMode variable to dismiss the current view.

The things become complex when you are looking to go back two times programmatically; or you want to proceed to two different pages conditionally based on a computation result; or you want to swap the current view to another view and do not destroy the view stack; or you want to conditionally jump to a new view stack and destroy the old one; and more.

In SwiftUI, you need to implement a bunch of @State to activate different routing and, if you want to activate them in a child view, you need to pass the Binding (could be multiple) all the way to that child. And in the parent view, you are also going to have a lot of different NavigationLink or one more @State to take the target view (and pass it through the constructors all the way to that child).

Elegant? Definitely not! So, what does the Defined Elements do?

Super easy routing

When we want to navigate to another page, Defined Elements provide the ability to do it in a nice short function call like link(to:) or jump(to:).

struct SamplePage: DefinedPage {
// This is the only requirement.
let controller: DefinedPageController = .init()

var main: some View {
Text("Navigate to LoginPage")
.onTapGesture {
// Navigate!
link(to: LoginPage())
}
}
}

You can also do automatically:

struct SamplePage: DefinedPage {
// This is the only requirement.
let controller: DefinedPageController = .init()

var main: some View {
Text("Navigate to LoginPage automatically")
}

// Run automatically when page is loaded.
func onPageLoaded() {
// Navigate!
link(to: LoginPage())
}
}

Then, what should we do to go back? Fairly simple!

struct SamplePage: DefinedPage {
// This is the only requirement.
let controller: DefinedPageController = .init()

var main: some View {
Text("Your Back Button")
.onTapGesture {
// Navigate to the previous page!
back()
}
}
}

Dynamic status bar style

Have you ever suffered in the issue of Status Bar Style? Now you can do it in a very short way.

We are going to handle it in our DefinedPage system. What you need to do is simply a definition of statusBarStyle in your DefinedPage.

struct SamplePage: DefinedPage {
// Simply define it!
var statusBarStyle: UIStatusBarStyle = .darkContent

var main: some View {
...
}
}

Oh, do you need to change the status bar style dynamically? For example, you want to change the status bar style when users are scrolling over a specific point? Easy! Just make it an @State variable, and you are good to go.

struct SamplePage: DefinedPage {
// Simply make it dynamically changable!
@State var statusBarStyle: UIStatusBarStyle = .darkContent

var main: some View {
...
}
}

Global font configuration

Set a font globally in your app? Get tired of having to set the font for every single Text in SwiftUI? Want to make it easy to change the font globally? Here is your sweet solution by using DefinedText with DefinedFont.

struct SamplePage: DefinedPage {
var main: some View {
// Use it globally!
DefinedText("Hello, world!")
}

func beforePageLoading() {
// Just set it once!
DefinedFont.setDefault(.init("MiSans"))
}
}

And more!

It is not the end! We have a whole more to say, and we decide to put it throughout the entire documentation instead of in the glimpse. We have a lot of pre-built out-of-box user-friendly components to make your development easier and your users happier. Go and check it out!

Why aren't we perfect yet?

Yes, nothing is perfect. So does the Defined Elements.

Currently, we have not done any optimization over the native SwiftUI and have not evaluated the rendering performance of the Defined Elements. So, when there is a huge amount of things to be rendered, the problem will remain the same with native SwiftUI or even worse. And, due to the restriction of SwiftUI's View system, we cannot run our view modifiers in a traditional ViewModifier because there will not be any context in a ViewModifier. So we end up use our own DefinedViewModifier, which may cause some performance issue in some special cases before we built our own interpreter over the View system (but that will loss some native SwiftUI ability over our components). We will continue to find a possible solution for the problem.

Besides, most of our components are still based on native Swift and SwiftUI, which has some limitations (they were intended to make SwiftUI a safe language, and they actually make SwiftUI not really handy). For example, to do the page routing, you need to implement a DefinedPageController. It should be done by our framework (by our initial design), but Swift language does not allow developers to initialize a persistent variable in protocol, so it ends up to something that you need to initialize manually.

For more issues and bugs, check our Issue Tracker.