<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Vince MingPu Shao</title>
    <description>The latest articles on Forem by Vince MingPu Shao (@vince19972).</description>
    <link>https://forem.com/vince19972</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F104228%2F96a825f8-266e-44a1-8160-60ee59b1fde9.jpeg</url>
      <title>Forem: Vince MingPu Shao</title>
      <link>https://forem.com/vince19972</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vince19972"/>
    <language>en</language>
    <item>
      <title>How to build design system with SwiftUI</title>
      <dc:creator>Vince MingPu Shao</dc:creator>
      <pubDate>Fri, 13 Sep 2019 01:15:55 +0000</pubDate>
      <link>https://forem.com/vince19972/how-to-build-design-system-with-swiftui-58h5</link>
      <guid>https://forem.com/vince19972/how-to-build-design-system-with-swiftui-58h5</guid>
      <description>&lt;p&gt;Building a design system to support one product is not easy - it has to be robust and flexible at the same time for scalability. Though challenging, &lt;a href="https://www.designbetter.co/design-systems-handbook/building-design-system" rel="noopener noreferrer"&gt;lots&lt;/a&gt; &lt;a href="https://lightningdesignsystem.com/design-tokens/" rel="noopener noreferrer"&gt;of&lt;/a&gt; &lt;a href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421" rel="noopener noreferrer"&gt;great&lt;/a&gt; &lt;a href="https://www.youtube.com/watch?v=wDBEc3dJJV8" rel="noopener noreferrer"&gt;resources&lt;/a&gt; have shared useful principles and approaches that help teams build a good system both visually and programmatically. Standing on their shoulders, this article tries to contribute to an untouched ground by focusing on building a good system in &lt;code&gt;SwiftUI&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do I write this article
&lt;/h2&gt;

&lt;p&gt;During my first summer in &lt;a href="https://tisch.nyu.edu/itp" rel="noopener noreferrer"&gt;ITP&lt;/a&gt; at New York, I'm lucky to have the opportunity to work as an iOS developer intern at &lt;a href="https://www.linebreak.studio/" rel="noopener noreferrer"&gt;Line Break Studio&lt;/a&gt;. One task I've been assigned to is building a design system in two steps: first visually in &lt;a href="https://www.sketch.com/" rel="noopener noreferrer"&gt;Sketch&lt;/a&gt;, and then programmatically in &lt;code&gt;SwiftUI&lt;/code&gt;. The experience of experimenting with the new framework and building a design system with it has been amazing, but also buggy along the way. That's why we'd like to share our experience with the community, hopefully making your development process easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is &lt;a href="https://developer.apple.com/documentation/swiftui" rel="noopener noreferrer"&gt;SwiftUI&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Apple released this groundbreaking new framework in &lt;a href="https://developer.apple.com/videos/wwdc2019/?q=swiftui" rel="noopener noreferrer"&gt;WWDC 2019&lt;/a&gt;, which is one of the bests in years. From the point of view as a web developer, the project development experience in &lt;code&gt;SwiftUI&lt;/code&gt; is closer to which in conventional front-end stack and frameworks. &lt;/p&gt;

&lt;p&gt;This is definitely an awesome move because programming interface and managing states are drastically easier than before. And the best part of this improvement is that one can &lt;a href="https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit" rel="noopener noreferrer"&gt;integrate &lt;code&gt;UIKit&lt;/code&gt; and &lt;code&gt;SwiftUI&lt;/code&gt; smoothly&lt;/a&gt;. To learn the basics of SwiftUI, the &lt;a href="https://developer.apple.com/tutorials/swiftui/tutorials" rel="noopener noreferrer"&gt;official tutorials&lt;/a&gt; provided by Apple are very helpful.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/aH7oWxfxpJY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo project
&lt;/h2&gt;

&lt;p&gt;For demonstration purpose, I put up a simplified version of design system we built in &lt;a href="https://www.linebreak.studio/" rel="noopener noreferrer"&gt;Line Break Studio&lt;/a&gt;. It a set of &lt;strong&gt;button&lt;/strong&gt; components in different forms, which are built on top of two lower level parts: &lt;strong&gt;typography&lt;/strong&gt; and &lt;strong&gt;colorPalette&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F82z5zpuwd8j4liybv9yz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F82z5zpuwd8j4liybv9yz.gif" alt="Dynamic rendering view of the demo project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project is &lt;a href="https://github.com/vince19972/SwiftUI-Design-System-Demo" rel="noopener noreferrer"&gt;public on GitHub&lt;/a&gt;, and I'm using &lt;code&gt;Xcode 11 Beta 5&lt;/code&gt; for development. An &lt;a href="https://airtable.com/shrHQdv9vQGz7UMQj" rel="noopener noreferrer"&gt;Airtable base&lt;/a&gt; as design system management hub (read &lt;a href="https://www.vinceshao.com/blog/a-better-web-development-workflow-confluence-airtable-jira-and-abstract" rel="noopener noreferrer"&gt;more about workflow management&lt;/a&gt;) is also public for reference.&lt;/p&gt;




&lt;h2&gt;
  
  
  Principles of building design system
&lt;/h2&gt;

&lt;p&gt;Design system in code is a middleware between designers and developers. Developer of the system takes inputs from design system in visual form, and produces &lt;code&gt;API&lt;/code&gt; that's identical with which for further development. Following two principles should be recognized to complete this system in code:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Communicate with &lt;a href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421" rel="noopener noreferrer"&gt;tokens&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Fundamentally, the purpose of having a design system in program is not about better code management or development efficiency, but to make sure the &lt;strong&gt;view&lt;/strong&gt; is consistent with design files. To achieve that goal, using tokens to signify certain color, font, size or any visual elements is crucial to maintain quality of communication between developers, designers and managers in a team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnepr6feriau7vrkt0wb9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnepr6feriau7vrkt0wb9.jpg" alt="Lightning Design System's tokens built by Salesforce"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Levels of hierarchy
&lt;/h3&gt;

&lt;p&gt;In &lt;a href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421" rel="noopener noreferrer"&gt;EightShapes' article&lt;/a&gt;, it points out that we should "Show options first, then decisions next", because "You can't make decisions without options."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flrzseaarnwdhzmumjbzv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flrzseaarnwdhzmumjbzv.jpg" alt="[EightShapes' article](https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421) about design tokens"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This kind of ordering architecture loosens the degree of coupling between different levels, hence providing more flexibility and dynamic for possible revisions. The way I structure the levels is in this order from bottom to top: material → base → token. But it could be anyway the team's comfortable with.&lt;/p&gt;




&lt;h2&gt;
  
  
  Diving into code
&lt;/h2&gt;

&lt;p&gt;Following section is a list of highlights we'd like to point out based on our experience. Please &lt;a href="https://github.com/vince19972/SwiftUI-Design-System-Demo" rel="noopener noreferrer"&gt;visit the GitHub repo&lt;/a&gt; for complete code. Any feedbacks or critics are welcome for improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Architecting levels of hierarchy
&lt;/h3&gt;

&lt;p&gt;There're two ways of stacking materials at lower level to construct tokens at highest level:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Use &lt;code&gt;enum&lt;/code&gt; for type safety and code literacy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Advantages of using &lt;code&gt;enum&lt;/code&gt; in code as grouping wrapper or parameter in function have already been well recognized. One point worths mentioning here is the implementation of levels of hierarchy. &lt;/p&gt;

&lt;p&gt;We always store the raw values, including font size (&lt;code&gt;CGFloat&lt;/code&gt;) and font name (&lt;code&gt;String&lt;/code&gt;), at the lowest level, because we don't want to mess around with it. But because raw value must be a literal in &lt;code&gt;enum&lt;/code&gt;, we can't just assign a &lt;code&gt;case&lt;/code&gt; to be a value from the other &lt;code&gt;enum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To work around this problem, we implement a function &lt;code&gt;getValue&lt;/code&gt;, which returns the raw value in &lt;code&gt;switch&lt;/code&gt; case when necessary. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;- Use &lt;code&gt;struct&lt;/code&gt; for easier structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Though enum is great, we don't need its unique feature in some cases. For example, because &lt;code&gt;Xcode&lt;/code&gt; takes care of the heavy job of processing dynamic colors, and no parameter options are required in API endpoint, we can set up color palettes by a simple two levels of struct. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  2. Clear and straightforward naming of &lt;code&gt;API&lt;/code&gt; endpoint
&lt;/h3&gt;

&lt;p&gt;Naming convention is another broad topic for discussion and debate. In addition to basic &lt;a href="https://swift.org/documentation/api-design-guidelines/" rel="noopener noreferrer"&gt;Swift conventions&lt;/a&gt;, the only two rules we abide are, 1) no acronym and 2) making it simple. For example, to use typography and color system, instead of creating new endpoints, we make &lt;code&gt;extension&lt;/code&gt; from &lt;code&gt;Font&lt;/code&gt; and &lt;code&gt;Color&lt;/code&gt; structs. This approach decreases the effort to memorize unfamiliar API names for developers. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  3. Manage color sets dynamically in two modes
&lt;/h3&gt;

&lt;p&gt;So dark mode has become a standard in industry, and both &lt;a href="https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/dark-mode/" rel="noopener noreferrer"&gt;iOS&lt;/a&gt; and &lt;a href="https://material.io/design/color/dark-theme.html" rel="noopener noreferrer"&gt;Android&lt;/a&gt; team have implemented this feature. It's a good trend for users, but could bring designers and developers some challenges, including managing and naming the color sets, especially gray scale ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh5vpz8jrztmjsqxln6lg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh5vpz8jrztmjsqxln6lg.jpg" alt="Material Design's dark theme guide"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To think and communicate about gray scale colors dynamically, using terms like &lt;em&gt;white&lt;/em&gt;, &lt;em&gt;light&lt;/em&gt;, &lt;em&gt;black&lt;/em&gt; or &lt;em&gt;dark&lt;/em&gt; doesn't work. Because if we referred to a dynamic color &lt;code&gt;#000000&lt;/code&gt; (black in HEX) &lt;em&gt;black&lt;/em&gt; or &lt;em&gt;dark&lt;/em&gt; in &lt;code&gt;light color scheme&lt;/code&gt;, how do you talk about this particular color, which should turn into &lt;code&gt;#FFFFFF&lt;/code&gt; (white in HEX), in &lt;code&gt;dark color scheme&lt;/code&gt;? &lt;em&gt;defaultDark&lt;/em&gt; or &lt;em&gt;lightDark&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh8hncba884817a4sa24w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh8hncba884817a4sa24w.jpg" alt="Confusing transition of color sets"&gt;&lt;/a&gt;&lt;/p&gt;
Confusing transition of color sets



&lt;p&gt;It is very confusing to name gray scale dynamic color sets in conventional approach. To avoid this confusion, we use &lt;code&gt;theme&lt;/code&gt; and &lt;code&gt;contrast&lt;/code&gt; to manage one set of color in &lt;code&gt;light&lt;/code&gt; and &lt;code&gt;dark&lt;/code&gt; schemes instead. Please see this table as reference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fivrk56mpqs68uel2tnzg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fivrk56mpqs68uel2tnzg.jpg" alt="Example color naming in demo Airtable base"&gt;&lt;/a&gt;&lt;/p&gt;
Example color naming in demo Airtable base



&lt;p&gt;Note that a gray scale color doesn't always need to be reversed in opposite color mode. In these situations that light color remains light and dark remains dark, we simply name name it light or dark instead. &lt;/p&gt;

&lt;p&gt;Once we wrap our head around this naming method, managing this architecture of color palette is easy in &lt;code&gt;Xcode&lt;/code&gt;. To create a color set, simply create a new &lt;code&gt;Asset Catalog&lt;/code&gt; file → add a new &lt;code&gt;Color Set&lt;/code&gt; → and change &lt;code&gt;Appearances&lt;/code&gt; to &lt;code&gt;Any, Light, Dark&lt;/code&gt; will do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fu52q88r4qyo56idawd56.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fu52q88r4qyo56idawd56.jpg" alt="How to add color asset in Xcode"&gt;&lt;/a&gt;&lt;/p&gt;
How to add color asset in Xcode



&lt;h3&gt;
  
  
  4. &lt;code&gt;environment&lt;/code&gt; settings
&lt;/h3&gt;

&lt;p&gt;One awesome feature in SwiftUI framework is the &lt;a href="https://developer.apple.com/documentation/swiftui/environment" rel="noopener noreferrer"&gt;environment modifier&lt;/a&gt;, which provides ability to control &lt;a href="https://developer.apple.com/documentation/swiftui/environmentvalues" rel="noopener noreferrer"&gt;environment values&lt;/a&gt; on target view. In terms of building design system, this ability provides convenient approach to change app's font at root level. And the other advantage of using &lt;code&gt;environmentValue&lt;/code&gt; is to change and test light and dark color schemes in development.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  5.&lt;code&gt;buttonStyle&lt;/code&gt; and button label
&lt;/h3&gt;

&lt;p&gt;Comparing to the old days in &lt;a href="https://developer.apple.com/documentation/uikit" rel="noopener noreferrer"&gt;UIKit&lt;/a&gt;, constructing reusable buttons in SwiftUI is drastically easier. The &lt;a href="https://developer.apple.com/documentation/swiftui/button" rel="noopener noreferrer"&gt;Button view&lt;/a&gt; consists of two parts, which are &lt;code&gt;action&lt;/code&gt; closure (event to be fired as button is pressed) and &lt;code&gt;label&lt;/code&gt; (body of the button). The view can then be chained with a modifier &lt;code&gt;buttonStyle&lt;/code&gt;. To learn details about building reusable buttons,I recommend reading &lt;a href="https://alejandromp.com/blog/2019/06/22/swiftui-reusable-button-style/" rel="noopener noreferrer"&gt;Alejandro's tutorial&lt;/a&gt;, which is comprehensive and useful. &lt;/p&gt;

&lt;p&gt;In our customized button components, first step is to create two structs, including &lt;code&gt;TokenButtonLabel&lt;/code&gt; and &lt;code&gt;TokenButtonStyle&lt;/code&gt;. These two structs are programmed according to the types of buttons we have in design files. For example, there're only two types of labels: icon and text. Each type has an according &lt;code&gt;init&lt;/code&gt; function designed with different parameters for new instances.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;On the other hand, there're four major types of button styles: circle icon, icon, capsule and text. To follow &lt;code&gt;ButtonStyle&lt;/code&gt; protocol, a &lt;code&gt;makeBody&lt;/code&gt; func has to be implemented. This function brings us a &lt;code&gt;configuration&lt;/code&gt; property, providing a native &lt;code&gt;isPressed&lt;/code&gt; value to monitor if the button is pressed or not.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, stacking on top of &lt;code&gt;TokenButtonLabel&lt;/code&gt; and &lt;code&gt;TokenButtonStyle&lt;/code&gt;, the endpoint of the button component API will be &lt;code&gt;TokenButton&lt;/code&gt; - a grouping that wraps content and style of button together, conforming to the button types in visual design system.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  6. &lt;code&gt;AnyView&lt;/code&gt; as wrapper
&lt;/h3&gt;

&lt;p&gt;As we're dealing with the &lt;code&gt;makeBody&lt;/code&gt; function brought by &lt;code&gt;ButtonStyle&lt;/code&gt; protocol, we found a useful tip to work with &lt;code&gt;View&lt;/code&gt;. To store a view in a variable, the type annotation could be indicated as &lt;code&gt;AnyView&lt;/code&gt;, which works as a general container of views in SwiftUI. &lt;/p&gt;

&lt;p&gt;In our case, because we want to add the opacity modifier to &lt;code&gt;configuration.label&lt;/code&gt; to all types of buttons, instead of doing so repeatedly in each &lt;code&gt;switch&lt;/code&gt; case, it makes more sense to chain the modifier at the end altogether. We can achieve this pattern by using the advantage of &lt;code&gt;AnyView&lt;/code&gt; in this way:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  7. Build view modifier with &lt;code&gt;mutating&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;To update styles of the buttons dynamically, we can build our own modifier. First instantiate customized mutable state properties in view, and then create a &lt;code&gt;mutating&lt;/code&gt; function which returns a &lt;code&gt;Self&lt;/code&gt; type after updating the target state property.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  8. Tricky border style
&lt;/h3&gt;

&lt;p&gt;One drawback of SwiftUI is styling a circle shape with circular border is not straightforward at all. I struggled for a while, and finally found a &lt;a href="https://stackoverflow.com/questions/57269651/add-a-border-with-cornerradius-to-an-image-in-swiftui-xcode-beta-5" rel="noopener noreferrer"&gt;solution here on StackOverflow&lt;/a&gt;. A &lt;code&gt;clipShape&lt;/code&gt; and an &lt;code&gt;overlay&lt;/code&gt; modifier are required to make it work.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SwiftUI is an incredible improvement Apple makes. Though flaws still exist, building a robust and flexible design system with it, and furthermore complicated UI in iOS is way efficient than ever. I hope this article is helpful for any iOS team trying to build UI, and always welcome to any feedbacks!&lt;/p&gt;

&lt;p&gt;👉 Read more of my works on &lt;a href="https://www.vinceshao.com" rel="noopener noreferrer"&gt;vinceshao.com&lt;/a&gt;&lt;br&gt;
👉 This article is also published on &lt;a href="https://www.freecodecamp.org/news/using-swiftui-to-build-design-system/" rel="noopener noreferrer"&gt;freeCodeCamp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>swift</category>
      <category>design</category>
      <category>ios</category>
      <category>app</category>
    </item>
  </channel>
</rss>
