-
Notifications
You must be signed in to change notification settings - Fork 5
Case Study: Cloning Swift UI's Text view
Swift UI has a view called Text
, which roughly approximates Flutter's Text
widget. This case study is intended to help you clone other Swift UI views in this package by showing you the analysis and approach that was used to clone the Text
widget.
While the Text
view is a fundamental piece of Swift UI, it doesn't implement a huge variety of behaviors. To spec the work, the Swift UI API docs were replicated in an issue ticket, along with some cloning instructions: https://github.com/Flutter-Bounty-Hunters/swift_ui/issues/2
The issue ticket includes some specification analysis, but we'll replicate that analysis here.
A perpetual challenge when cloning Swift UI is dealing with Swift UI initializers. Swift UI, similar to many other languages, supports method overloading. This means methods, such as initializers, can declare different groups of parameters, without defining separate names. For example, here are a few Text
initializers from Swift UI:
init(LocalizedStringKey, tableName: String?, bundle: Bundle?, comment: StaticString?)
Creates a text view that displays localized content identified by a key.
init(LocalizedStringResource)
Creates a text view that displays a localized string resource.
init<S>(S)
Creates a text view that displays a stored string without localization.
init(verbatim: String)
Creates a text view that displays a string literal without localization.
Notice that each of these initializers are defined via init()
. They don't have different names. Dart can't do this, so the swift_ui
package needs to use named constructors to support such situations.
At the time of cloning the Text
view, this package lacked a number of concepts, such as a swift_ui
package version of LocalizedStringKey
and LocalizedStringResource
. It's unclear whether those will be implemented, or how. But, to be safe, the initial implementation should include constructors for those cases. We can delete them later, if we don't need them.
There are generally two goals when cloning swift_ui
initializers. All things being equal, create fewer named constructors than more named constructors, so Swift UI developers don't feel overwhelmed with the number of options. All things being equal, use shorter names over longer names, so that Swift UI developers don't feel like they're typing a lot more than they're used to.
In the case of Text
, we chose the following constructors:
class Text extends StatefulWidget {
/// Creates a `Text` widget that displays a string with default localization.
Text(String localizedPlainText);
/// Creates a `Text` widget that displays a string literal without localization.
Text.verbatim(String verbatimPlainText);
/// Creates a `Text` widget that displays text associated with a [localizedStringKey].
Text.localString(this.localizedStringKey, {
this.tableName,
this.bundle,
this.comment,
});
/// Creates a `Text` widget that displays attributed text, which might contain
/// various styles throughout subsections of the text.
Text.attributed(this.attributedText);
/// Creates a `Text` widget that displays a localized range between two dates.
Text.dateRange(this.dateRange);
/// Creates a `Text` widget that displays a localized time interval.
Text.timeInterval(this.timeInterval);
/// Creates a `Text` widget that displays localized dates and times using a specific [style].
Text.date(this.date, this.dateStyle);
// TODO: Creating a text view with formatting
// TODO: Creating a text view from an image
// TODO: Creating a text view with a timer
}