<?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>DEV Community: CometChat</title>
    <description>The latest articles on DEV Community by CometChat (@cometchat).</description>
    <link>https://dev.to/cometchat</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%2Forganization%2Fprofile_image%2F1669%2Fa76738ec-9e52-42f6-8202-6df4cc618c15.png</url>
      <title>DEV Community: CometChat</title>
      <link>https://dev.to/cometchat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cometchat"/>
    <language>en</language>
    <item>
      <title>25 Developer Blogs to Keep You at the Top of Your Game</title>
      <dc:creator>kushal khandelwal</dc:creator>
      <pubDate>Wed, 16 Jun 2021 12:32:38 +0000</pubDate>
      <link>https://dev.to/cometchat/25-developer-blogs-to-keep-you-at-the-top-of-your-game-4l36</link>
      <guid>https://dev.to/cometchat/25-developer-blogs-to-keep-you-at-the-top-of-your-game-4l36</guid>
      <description>&lt;p&gt;The field of software engineering is constantly developing. (ba dum tss) With tech, frameworks, and programming best practices changing every day—even the best developers risk falling behind. &lt;/p&gt;

&lt;p&gt;Nobody really wants to dedicate large chunks of their time to continued education. We get that. Fortunately, the internet is littered with developer blogs. And, we can definitely innovate, grow and learn from the trials and errors of others so we don't have to waste time ourselves.&lt;/p&gt;

&lt;p&gt;If you're part of team "Never Stop Learning", check out some of our favorite developer blogs:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Stack Overflow
&lt;/h2&gt;

&lt;p&gt;With over 100 million visitors each month, Stack Overflow is one of the most popular websites in the world. In this case, the popularity is well deserved. The question-and-answer website for developers was built around the idea of knowledge sharing and reuse. It encourages its readers to reuse what others have already learned, created and proven to build new things of value. An emphasis on two-way conversation and altruistic mentorship makes Stack Overflow much more than a developer blog—it’s a powerful developer community. &lt;/p&gt;

&lt;p&gt;Recommended blog: If you’re like every other developer in the world &lt;a href="https://stackoverflow.com/questions/927358/how-do-i-undo-the-most-recent-local-commits-in-git?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=stackoverflow&amp;amp;utm_content=this%20question"&gt;this question&lt;/a&gt; may interest you. (Okay, technically it has only been viewed 9.5 million times)&lt;/p&gt;

&lt;h2&gt;
  
  
  2. DEV Community
&lt;/h2&gt;

&lt;p&gt;Have you considered starting or contributing to a developer blog? If so, DEV Community is a great place to get your feet wet. The team at DEV works diligently to foster an open and welcoming environment, making Dev.to arguably the most positive and friendly development community on the internet. While this blog does skew toward beginners and enthusiastic contributors, it’s still chock-full of entertaining and informative articles. Plus, with more than 600,000 software developers, DEV Community is a go-to place for collaboration and networked learning.&lt;/p&gt;

&lt;p&gt;Recommended blog: Dive in with this &lt;a href="https://dev.to/ender_minyard/full-stack-developer-s-roadmap-2k12?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=devto&amp;amp;utm_content=full%20stack%20development"&gt;article on full stack development&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. HackerNoon
&lt;/h2&gt;

&lt;p&gt;HackerNoon is one of the best tech blogs out there. Covering everything from AI news and blockchain to gaming, it’s known for free, high-quality, in-depth tech stories. The wide variety of article topics ensures there’s something for everyone—whether you’re a recent grad trying to rock their first job, a single dad learning to code on the side or a leading woman in tech looking for a safe place to share and grow. &lt;/p&gt;

&lt;p&gt;Recommended blog: Hop on the NFT train with this &lt;a href="https://hackernoon.com/why-is-everyone-going-crazy-over-nft-11m33ea?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=hackernoon"&gt;article&lt;/a&gt; by Hacker Noon. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. freeCodeCamp
&lt;/h2&gt;

&lt;p&gt;freeCodeCamp is exactly that—a nonprofit community that helps developers learn to code through challenges and projects. They offer multiple, self-paced certifications including responsive web design, data visualization, scientific computing with python, information security and more. Each certification takes about 300 hours of dedicated learning time to complete, but you can jump around from challenge to challenge in freeCodeCamp’s open curriculum depending on your goals. In addition to coding challenges, you can gain experience by contributing to open source projects used by other nonprofit organizations. And, if you get stuck, there is a chat server where you can talk to other campers and alumni to get help and make connections. &lt;/p&gt;

&lt;p&gt;Recommended blog: Tired of writing long if/else statements in JavaScript? freeCodeCamp has got you covered with &lt;a href="https://www.freecodecamp.org/news/ternary-operator-javascript-if-statement-tutorial/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=freecodecamp"&gt;this guide on ternary operators&lt;/a&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Indie Hackers
&lt;/h2&gt;

&lt;p&gt;Indie Hackers is where the best developer blogs and the best entrepreneur blogs meet (and swap war stories). An indie hacker, as defined by the website founder himself, is a person building an online project that can generate revenue. The Indie Hackers blog is geared towards helping independent entrepreneurs become and remain profitable—with owners of successful side projects and founders of profitable startups sharing their tips and tricks. If you’re an aspiring entrepreneur, Indie Hacker provides a great forum for shared knowledge, ideas and support. &lt;/p&gt;

&lt;p&gt;Recommended blog: Not every venture is a success, but Indie Hackers knows you can learn just as much (if not more) from the failures. See for yourself with &lt;a href="https://omert.net/startup-failure-story/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=indiehackers"&gt;this startup story&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. A List Apart
&lt;/h2&gt;

&lt;p&gt;A List Apart started as a mailing list in 1997. That’s right, old-fashioned letter writing at it’s finest.  The website launched in 1998 and, since then, has grown into a must-read software engineering blog for curious coding minds. A List Apart explores the design, development and meaning of web content with a special focus on web standards and best practices. With a clear, well-organized topic index, A List Apart makes it easy to find and consume high-quality, evergreen content on the developer topic of your choosing. &lt;/p&gt;

&lt;p&gt;Recommended blog: New to A List Apart? Get started with this &lt;a href="https://alistapart.com/article/dao/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=alistapart"&gt;great article for new readers&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  7. GeeksforGeeks
&lt;/h2&gt;

&lt;p&gt;GeeksforGeeks is written for the yearning programmer within all of us. Or, at least within all of us geeks. Built around the motto “Don’t Learn Alone”, Geeks is a developer blog with everything—articles, tutorials, webinars, courses, etc. But it’s primary goal is to help hungry programmers prepare for the interviews and meetings that will land them their dream job.&lt;/p&gt;

&lt;p&gt;Recommended blog: Start on the path to your dream job with GeekforGeeks &lt;a href="https://www.geeksforgeeks.org/100-days-of-code-a-complete-guide-for-beginners-and-experienced/?ref=grb&amp;amp;utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=geeksforgeeks"&gt;100 days of Code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. HoneyPot
&lt;/h2&gt;

&lt;p&gt;.cult by Honeypot exists to tell the untold developer stories that help developers around the world know their worth. And, more importantly, how to fight for themselves professionally. With documentaries, podcasts and articles designed to help developers navigate their careers, .cult by HoneyPot answers all the questions you didn’t even know you had. &lt;/p&gt;

&lt;p&gt;Recommended blog: Figure out where you stand in the market with HoneyPot’s &lt;a href="https://cult.honeypot.io/developer-salary-report-2021?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=honeypot"&gt;2021 developer salary report&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Several People Are Coding
&lt;/h2&gt;

&lt;p&gt;A spinoff of Slack’s “Several People Are Typing” blog, this slack engineering blog features content from the entire Slack engineering team. As a company that’s constantly changing and quickly growing, Slack has seen it all. Several People Are Coding provides an opportunity to learn from the Slack team’s experience with insightful articles on the challenges they’ve faced and the lessons they’ve learned. &lt;/p&gt;

&lt;p&gt;Recommended blog: Get a behind-scenes-look at how Slack’s top developers think through iterative improvements on their product in this &lt;a href="https://slack.engineering/creating-a-react-analytics-logging-library/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=slackengineering"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Coding Horror
&lt;/h2&gt;

&lt;p&gt;Ask a software engineer what their favorite developer blog is and there’s a good chance you’ll hear, “Coding Horror.” Written by the creator of Stack Overflow, Coding Horror offers a refreshing take on the day-to-day realities (and struggles) of living the developer life. People love this blog. It’s honest, it’s witty and it covers the topics that software developers really care about.&lt;/p&gt;

&lt;p&gt;Recommended blog: As more and more companies go remote, developers find themselves competing with people all over the world for the same jobs. Learn what you can do to stand out in this &lt;a href="https://blog.codinghorror.com/be-good-at-your-job/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=codinghorror"&gt;blog post&lt;/a&gt; that proves Coding Horror may have always been ahead of its time.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. The Daily WTF
&lt;/h2&gt;

&lt;p&gt;The Daily WTF is exactly what you’d expect it to be—a user-submitted blog that highlights the WTF moments of real coders around the globe. It’s a “What Not To Do” guide for developing software, whether independently or on a team. Join for the disastrous coding examples, stay for the “Thank God That’s Not My Problem” anecdotes.&lt;/p&gt;

&lt;p&gt;Recommended blog: Speaking of “Thank God That’s Not My Problem” anecdotes, you’ll definitely want to read about &lt;a href="https://thedailywtf.com/articles/The_Big_Red_Button?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=dailywtf"&gt;the big red button&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Hacker News
&lt;/h2&gt;

&lt;p&gt;Run by YCombinator, Hacker News is a social news site focused on software development and entrepreneurship. The digital forum consists of user-submitted entries. Each entry is ranked and vetted by fellow developers and entrepreneurs in the software space, ensuring that only high-quality and relevant posts reach the top of the discussion board. It’s the go-to spot of many in the industry for developer news and updates. &lt;/p&gt;

&lt;p&gt;Recommended blog: See what’s &lt;a href="https://news.ycombinator.com/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=hackernews"&gt;popular on Hacker News&lt;/a&gt; right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Product Hunt
&lt;/h2&gt;

&lt;p&gt;If you’re interested in keeping up with the best new products in tech, you’ll be interested in Product Hunt. It’s a curation of user-submitted products with easy options for finding, sharing and evaluating each piece of new tech. Whether you’re looking to buy, looking to build or just looking to judge—there’s something for everyone.&lt;/p&gt;

&lt;p&gt;Recommended blog: Get started with &lt;a href="https://www.producthunt.com/posts/remote-ok?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=producthunt"&gt;one of the most upvoted products in Product Hunt’s history&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  14. MIT Free Courses
&lt;/h2&gt;

&lt;p&gt;The concept of MIT OpenCourseWare grew out of a desire to spread knowledge and encourage collaboration among scholars around the world. What does this mean for you? It means that you can now take MIT courses for free online. That’s right. You can get an MIT education from the comfort of your own home, without paying a dime. You won’t have the degree, but you will have all the knowledge that comes from attending one of the best Universities for Computer Science in the world.  &lt;/p&gt;

&lt;p&gt;Recommended blog: Jump start your education by signing up for one of the &lt;a href="https://www.edx.org/course/introduction-to-computer-science-and-programming-7?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=mitcourses"&gt;most popular MIT free courses today&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  15. Slashdot
&lt;/h2&gt;

&lt;p&gt;Self-branded as "News for Nerds. Stuff that Matters", Slashdot is a large, interactive social news website. It features blog posts and news stories related to technology and coding and boasts a robust community of readers. If you’re a nerd looking for a place to discuss the “stuff that matters”, the Slashdot community is calling your name.&lt;/p&gt;

&lt;p&gt;Recommended blog: Explore the &lt;a href="https://slashdot.org/hof.shtml?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=slashdot"&gt;Slashdot Hall of Fame&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  16. CSS-Tricks
&lt;/h2&gt;

&lt;p&gt;Don’t let the name fool you, CSS-Tricks is not just about CSS. Really, CSS-Tricks is a developer blog about web development (and everything that entails). With a team of top-notch staff writers and loads of guest authors, CSS-Tricks offers high-quality content on a variety of tech topics including HTML, Typography, Accessibility, JavaScript, Forms and, yes, CSS. &lt;/p&gt;

&lt;p&gt;Recommended blog: Expand your knowledge on one of today’s hot developer topics, Flexbox, with this &lt;a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=csstricks"&gt;comprehensive Flexbox guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  17. The Netflix Tech Blog
&lt;/h2&gt;

&lt;p&gt;An underground company you’ve probably never heard of, Netflix is an American content platform and production company. The Netflix Tech Blog offers a peek into Netflix behind-the-scenes including designs, builds and operations. It also features writings from the entire Netflix developer team on anything and everything tech-related.&lt;/p&gt;

&lt;p&gt;Recommended blog: Ever wonder how Netflix serves up the background images you see? Me neither. But &lt;a href="https://netflixtechblog.com/growth-engineering-at-netflix-automated-imagery-generation-5a105fd51569?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=netflixtech"&gt;this article&lt;/a&gt; was very interesting nonetheless.&lt;/p&gt;

&lt;h2&gt;
  
  
  18. Dream.In.Code
&lt;/h2&gt;

&lt;p&gt;Dream.In.Code, or DIC for short, is a leading online community for programmers and web developers. DIC has gained a reputation in the tech community for providing expert dev help for students and professionals alike. And, with more than 400 new members registering every day, DIC is clearly a go-to hub for developers.&lt;/p&gt;

&lt;p&gt;Recommended blog: See what’s &lt;a href="https://www.dreamincode.net/forums/forum/76-programming-help?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=dreamincode"&gt;trending on Dream.In.Code&lt;/a&gt; right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  19. Google Developers
&lt;/h2&gt;

&lt;p&gt;Through Google Developers, the internet’s leading entity seeks to inspire coders across the globe. Bursting with tutorials, tips, and tools, the Google Developers blog content spans across Google’s many consoles for developers including the Google API Console, Google Play Store Developer Console and others.&lt;/p&gt;

&lt;p&gt;Recommended blog: Machine learning and AI are all the rage, but not many developers really know how to get started. This article does a great job of helping developers understand how to &lt;a href="https://developers.googleblog.com/2019/05/new-ml-kit-features-easily-bring.html?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=googledevelopers"&gt;bring Machine Learning into their projects&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  20.DZone
&lt;/h2&gt;

&lt;p&gt;DZone, in their own words, serves technology professionals with the knowledge, tools, and strategies they need to build the future. If that sounds like something that may interest you, you’re not alone. DZone is one of the world’s largest online communities—with more than 1 million developers already signed up. Dzone’s developer blog covers everything from agile to the cloud, devops, big data, integration, performance and more.&lt;/p&gt;

&lt;p&gt;Recommended blog: Writing JavaScript can get messy, &lt;a href="https://dzone.com/articles/structure-javascript-code?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=dzone"&gt;this article&lt;/a&gt; explains how to keep things neat and tidy with the Revealing Module pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  21. Women Who Code
&lt;/h2&gt;

&lt;p&gt;Women Who Code is a global nonprofit with a community of tech professionals dedicated to supporting one another in their career goals. The Women Who Code developer blog provides tutorials, articles, videos and other educational materials designed to help women excel in the tech space. The community consists of career-aged tech professionals at every level of the industry including software engineers, consultants, executives, data scientists, students, etc.  &lt;/p&gt;

&lt;p&gt;Recommended blog: Women Who Code discusses self-advocacy, communication and the importance of not being afraid to rock the boat in &lt;a href="https://www.womenwhocode.com/blog/engineer-to-engineer-don-t-be-afraid-to-rock-the-boat?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=womenwhocode"&gt;this edition of Engineer to Engineer&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  22. Smashing Magazine
&lt;/h2&gt;

&lt;p&gt;Smashing Magazine focuses on quality over quantity. Each article is carefully curated, edited and prepared by a small team of passionate professionals. The tech blog is committed to helping its readers nourish productivity, improve their design and development skills and perfect their work-life balance. Get coding tips, tricks and ideas that you know you can trust. &lt;/p&gt;

&lt;p&gt;Recommended blog: This &lt;a href="https://www.smashingmagazine.com/2021/04/guide-supported-modern-css-pseudo-class-selectors/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=smashingmag"&gt;detailed guide on CSS pseudo selectors&lt;/a&gt; is a great example of the level of quality you can expect from Smashing Magazine.&lt;/p&gt;

&lt;h2&gt;
  
  
  23. Simple Programmer
&lt;/h2&gt;

&lt;p&gt;Simple Programmer focuses on distilling complex dev topics into simple, easy-to-understand content. With an emphasis on holistic content, Simple Programmer offers a wide variety of topics on everything from the top reasons you should use python programming language to tackling the mental aspect of being a software developer. &lt;/p&gt;

&lt;p&gt;Recommended blog: In order to succeed as a software developer you need to be well rounded—an idea that Simple Programmer explores in &lt;a href="https://simpleprogrammer.com/soft-skills-developers-growing-career/?utm_source=dev.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=developerblogs&amp;amp;utm_term=simpleprogrammer"&gt;this blog&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  24. Reddit
&lt;/h2&gt;

&lt;p&gt;Hungry for more? Reddit’s community-based hubs are a great resource for developers. Get started with some of our favorite subreddits: &lt;/p&gt;

&lt;p&gt;r/codetogether&lt;br&gt;
r/coding&lt;br&gt;
r/compsci&lt;br&gt;
r/ComputerScience&lt;br&gt;
r/cscareerquestions&lt;br&gt;
r/dailyprogrammer&lt;br&gt;
r/diycompsci&lt;br&gt;
r/dotnet&lt;br&gt;
r/fosshelpwanted&lt;br&gt;
r/gamedev&lt;br&gt;
r/LearnWebDesign&lt;br&gt;
r/netsec&lt;br&gt;
r/progether&lt;br&gt;
r/programming&lt;br&gt;
r/programmingtools&lt;br&gt;
r/prograrticles&lt;br&gt;
r/softwarerequest&lt;br&gt;
r/tinycode&lt;br&gt;
r/web_design&lt;br&gt;
r/webdev &lt;/p&gt;

&lt;h2&gt;
  
  
  25. CometChat Blog
&lt;/h2&gt;

&lt;p&gt;The CometChat blog just so happens to be a personal favorite of ours—with articles and insights for developers, entrepreneurs and tech enthusiasts everywhere. We love what we do and we love talking about tech with … anyone who will listen (or even better, talk back). If you’re looking to learn a lot and be entertained a little, we hope you’ll check out a few more of our articles.&lt;/p&gt;

&lt;p&gt;Recommended articles: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dive in with &lt;a href="https://comet.chat/6ecc"&gt;best-in-class tutorials and open source examples&lt;/a&gt; designed to simplify the process of adding text, voice and video chat to mobile and web apps.&lt;/li&gt;
&lt;li&gt;Checkout this roundup of the most important &lt;a href="https://comet.chat/e5f9"&gt;app development trends&lt;/a&gt; that could disrupt the mobile app development industry&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What other blogs do you read to stay at the top of your game?&lt;/p&gt;

</description>
      <category>blogs</category>
      <category>learning</category>
      <category>codenewbie</category>
      <category>growth</category>
    </item>
    <item>
      <title>Build a jQuery Chat App</title>
      <dc:creator>NJOKU SAMSON EBERE</dc:creator>
      <pubDate>Fri, 11 Jun 2021 11:44:44 +0000</pubDate>
      <link>https://dev.to/cometchat/build-a-jquery-chat-app-2kn</link>
      <guid>https://dev.to/cometchat/build-a-jquery-chat-app-2kn</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Using a chat application can be very joyous. As we communicate with friends, families, partners and others, we feel a lot better. This is why developers around the world want to add this feature to their applications. But giving such a beautiful experience through writing of code is no child's play. It takes a whole lot of resources to make that happen. But there is good news!&lt;/p&gt;

&lt;p&gt;The good news is that this feature has been made available for you by a team that understands your needs. We are talking of the &lt;strong&gt;CometChat&lt;/strong&gt; team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com/" rel="noopener noreferrer"&gt;CometChat&lt;/a&gt; can be used to build chat features into our websites or mobile applications. The best part of it is that it supports 10+ languages/platforms. Even &lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; which many developers might feel is outdated is also been supported by CometChat. To prove that, I will be using this tutorial to guide you through building a Chat application using &lt;strong&gt;jQuery&lt;/strong&gt; and &lt;strong&gt;CometChat&lt;/strong&gt;. What we will build will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2yhntt0risvvz0d3zcd.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2yhntt0risvvz0d3zcd.JPG" alt="Sample App to be built" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we proceed, allow me to introduce you to &lt;a href="https://www.cometchat.com/" rel="noopener noreferrer"&gt;CometChat&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  CometChat
&lt;/h1&gt;

&lt;p&gt;CometChat provides Text chat &amp;amp; video calling solutions for your website and apps to quickly connect your users with each other - patients with doctors, buyers with sellers, teachers with students, gamers, community users, event attendees and more.&lt;/p&gt;

&lt;p&gt;For this tutorial, we will be focusing on the &lt;a href="https://www.cometchat.com/pro" rel="noopener noreferrer"&gt;CometChat Pro&lt;/a&gt; product. It houses highly customizable and easy-to-use  SDKs, UI kits, Extensions and Plugins. It also supports more than 10 programming languages and platforms as you may see in the &lt;a href="https://prodocs.cometchat.com/" rel="noopener noreferrer"&gt;docs here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With these information, you can see that what you can do with CometChat is only limited to your imagination. It could be solutions on Social community, Marketplace, Dating, On Demand, Edu-Tech, Live Stream and so on. &lt;strong&gt;Just Dream and Build with the support of CometChat&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Something really special about CometChat is that you are given a 30 days trial period after which you can decide to continue or not. But why will you not continue with such an awesome gift?&lt;/p&gt;

&lt;h1&gt;
  
  
  jQuery
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisite
&lt;/h1&gt;

&lt;p&gt;This tutorial assumes that you already have basic knowledge of &lt;em&gt;jQuery&lt;/em&gt; and &lt;em&gt;firebase&lt;/em&gt;. You can catch up with the following links if you are new to those technologies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;jQuery: &lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;https://jquery.com/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Firebase: &lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;https://firebase.google.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Firebase Auth: &lt;a href="https://firebase.google.com/docs/auth?authuser=0" rel="noopener noreferrer"&gt;https://firebase.google.com/docs/auth?authuser=0&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Setup CometChat Account and Chat Widget
&lt;/h1&gt;

&lt;p&gt;The first thing we need for this is to create an account with CometChat Pro. So let's get to that...&lt;/p&gt;

&lt;h2&gt;
  
  
  Create CometChat Pro Account
&lt;/h2&gt;

&lt;p&gt;Follow the next steps to quickly create a CometChat Pro account&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visit &lt;a href="https://app.cometchat.com/signup" rel="noopener noreferrer"&gt;https://app.cometchat.com/signup&lt;/a&gt;, signup and login&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwv7ybwxn73mmz00clqb.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwv7ybwxn73mmz00clqb.JPG" alt="CometChat Pro Signup page" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You should be on your dashboard like mine below:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffefq36tgoug1whszmjvr.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffefq36tgoug1whszmjvr.JPG" alt="CometChat Pro dashboard" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set Up a Chat Widget
&lt;/h2&gt;

&lt;p&gt;The chat widget helps us to configure CometChat in our jQuery website from our CometChat Pro dashboard. So we can control how the Chat functions on our jQuery website from our CometChat dashboard. To do this, we need to create an app in CometChat. &lt;/p&gt;

&lt;h3&gt;
  
  
  Create an App
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In your dashboard, click on the &lt;code&gt;Add New App&lt;/code&gt; button&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd81gtm1oxljvjg2ihrj.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd81gtm1oxljvjg2ihrj.JPG" alt="Add New App button" width="339" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fill out the screen that pops up and click on the &lt;code&gt;Add App&lt;/code&gt; button&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lao66vuspdw27hinw7a.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lao66vuspdw27hinw7a.JPG" alt="Create App Form" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should get this congratulatory popup. &lt;em&gt;Click on the &lt;code&gt;Get Started&lt;/code&gt; to be redirected to the dashboard of the app you just created&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0rggmz260oqe1sguewr.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0rggmz260oqe1sguewr.JPG" alt="congratulatory popup" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You should now be in that App's dashboard like so:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz10867a6t71j8yauah9.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz10867a6t71j8yauah9.JPG" alt="A CometChat App dashboard" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All Good! Your App has been created. You also have 30 days to do all you want for free&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue Chat Widget Setup
&lt;/h2&gt;

&lt;p&gt;By the left side of the App's dashboard you will find a side menu - a long list of menu items. Do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;code&gt;Chat Widget&lt;/code&gt; link&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flryqlxvtj9g4g5b5vhcx.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flryqlxvtj9g4g5b5vhcx.JPG" alt="Chat Widget link" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should now be presented with a button on the page to add new Chat Widget. Click on the button&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo23ff0bb8riczlm7bsy3.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo23ff0bb8riczlm7bsy3.JPG" alt="Alt Text" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And that is all that you need to create a Chat Widget. It has been created automatically on that one click&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvut8ioqn8jtysjweucp8.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvut8ioqn8jtysjweucp8.JPG" alt="Chat Widget Configurations" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notice that it contains details for installation by the right side of the screen. We will be using that in a short while.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Build a jQuery Website
&lt;/h1&gt;

&lt;p&gt;At this juncture, we have paused CometChat. Let's build our jQuery website where CometChat will be integrated later. The next steps will show us how to do that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new folder with the name &lt;strong&gt;CometChat-jQuery&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;jQuery&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create 5 files inside the folder:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;index.html&lt;/li&gt;
&lt;li&gt;login.html&lt;/li&gt;
&lt;li&gt;init.js&lt;/li&gt;
&lt;li&gt;index.js&lt;/li&gt;
&lt;li&gt;login.js&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;em&gt;index.html&lt;/em&gt; file, enter the following code&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"ie=edge"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;CometChat jQuery&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- firebase --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.gstatic.com/firebasejs/4.8.2/firebase.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.gstatic.com/firebasejs/4.8.2/firebase-auth.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"main_container"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to CometChat jQuery&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"logout();"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;logout&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- jQuery --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script
      &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.jquery.com/jquery-3.6.0.min.js"&lt;/span&gt;
      &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="&lt;/span&gt;
      &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- local scripts --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"init.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"index.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enter the following code in the &lt;em&gt;login.html&lt;/em&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"ie=edge"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;CometChat jQuery Login&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- firebase --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.gstatic.com/firebasejs/4.8.2/firebase.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.gstatic.com/firebasejs/4.8.2/firebase-auth.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
      &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt;
      &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
      &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.css"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- The surrounding HTML is left untouched by FirebaseUI.
         Your app may use that space for branding, controls and other customizations.--&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align: center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Login To Chat&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"firebaseui-auth-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- jQuery --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script
      &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.jquery.com/jquery-3.6.0.min.js"&lt;/span&gt;
      &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="&lt;/span&gt;
      &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"init.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"login.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the &lt;em&gt;init.js&lt;/em&gt; file, enter the following code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fireBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fireBase&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hasInit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ENTER CONFIG HERE&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasInit&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;hasInit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to your firebase console&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;project&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set the authentication method to &lt;strong&gt;email/password&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Copy firebase configuration&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste it within the &lt;em&gt;init.js&lt;/em&gt; file where it reads: &lt;code&gt;// ENTER CONFIG HERE&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, The following code will be in the &lt;em&gt;login.js&lt;/em&gt; file&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// FirebaseUI config.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;uiConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;signInSuccessUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;signInOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Leave the lines as is for the providers you want to offer your users.&lt;/span&gt;
    &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EmailAuthProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PROVIDER_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// Terms of service url.&lt;/span&gt;
  &lt;span class="na"&gt;tosUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize the FirebaseUI Widget using Firebase.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;firebaseui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AuthUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// The start method will wait until the DOM is loaded.&lt;/span&gt;
&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#firebaseui-auth-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uiConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For the &lt;strong&gt;index.js&lt;/strong&gt; file, enter the following code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;mainContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#main_container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;logout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;firebase&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onAuthStateChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// User is signed in.&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;mainContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// No user is signed in.&lt;/span&gt;
      &lt;span class="nx"&gt;mainContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redirect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having done all those work, load the &lt;em&gt;login.html&lt;/em&gt; file on your browser and you should have the following page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fdm06p165gk98h3neor.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fdm06p165gk98h3neor.JPG" alt="Login Page" width="762" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Login a user to get to the &lt;em&gt;index.html&lt;/em&gt; page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbddxl6f3act68gx2rq7.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbddxl6f3act68gx2rq7.JPG" alt="Index page" width="755" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the user has not been signed in before, then you will get the &lt;em&gt;Create Account&lt;/em&gt; page to sign up before being redirected to the &lt;em&gt;index.html&lt;/em&gt; page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxoozesfrc7mu2ax8phes.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxoozesfrc7mu2ax8phes.JPG" alt="Create Account Page" width="759" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What the jQuery Website does?&lt;/strong&gt;&lt;br&gt;
This website is an authentication application. It takes an email and if the email already exist, it requires the password and log the user in. On the other hand, if the email do no exist yet in the database, it asks the user for details to create a new account.  The following images demonstrates the application&lt;/p&gt;

&lt;p&gt;Create Account&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg75pa06zxhz7wlmdybd3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg75pa06zxhz7wlmdybd3.gif" alt="Create Account" width="335" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Login&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzsw1avlp9zumkp6lzzw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzsw1avlp9zumkp6lzzw.gif" alt="Login" width="333" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Awesome!!!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Integrate CometChat into the jQuery Website
&lt;/h1&gt;

&lt;p&gt;The time has now arrived for us to make the jQuery Website we just built a chat application using CometChat. To make that happen, we will be doing the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize &lt;strong&gt;CometChat&lt;/strong&gt; and &lt;strong&gt;CometChatWidget&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add the CometChat and CometChatWidget CDN to our &lt;code&gt;html&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Add the CometChat &lt;strong&gt;Logout&lt;/strong&gt; Logic&lt;/li&gt;
&lt;li&gt;Determine if a logged in user is a &lt;strong&gt;new&lt;/strong&gt; or &lt;strong&gt;returning&lt;/strong&gt; user&lt;/li&gt;
&lt;li&gt;Add the CometChat &lt;strong&gt;Login&lt;/strong&gt; Logic&lt;/li&gt;
&lt;li&gt;Add the CometChat &lt;strong&gt;Create User&lt;/strong&gt; Logic&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Let's do this!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;STEP 1:&lt;/strong&gt; Initialize &lt;strong&gt;CometChat&lt;/strong&gt; and &lt;strong&gt;CometChatWidget&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Initializing &lt;code&gt;CometChat&lt;/code&gt; and &lt;code&gt;CometChatWidget&lt;/code&gt; tells our application that we are ready to use CometChat in our application.&lt;/p&gt;

&lt;p&gt;Let's do this by adding the following code in our &lt;em&gt;init.js&lt;/em&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// cometchat initialization&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;appID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;appID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;region &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;appSetting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AppSettingsBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribePresenceForAllUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRegion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;appSetting&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Initialization completed successfully&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// You can now call login function.&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Initialization failed with error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// Check the reason for error and take appropriate action.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;

&lt;span class="c1"&gt;// cometchat widget initialization&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;CometChatWidget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;appID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;appID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;appRegion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;region&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;authKey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Initialization (CometChatWidget) completed successfully&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Initialization (CometChatWidget) failed with error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;//Check the reason for error and take appropriate action.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ensure to replace &lt;code&gt;appID&lt;/code&gt;, &lt;code&gt;region&lt;/code&gt; and &lt;code&gt;authKey&lt;/code&gt; with yours&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's going in the code above?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;In the code you just entered, &lt;code&gt;CometChat&lt;/code&gt; and &lt;code&gt;CometChatWidget&lt;/code&gt; initializations are being automatically invoked once your application loads completely on the browser. The self-invoking function &lt;code&gt;(function{})()&lt;/code&gt; ensures that this happens. Now we are ready to use &lt;code&gt;CometChat&lt;/code&gt; and &lt;code&gt;CometChatWidget&lt;/code&gt; in our application.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  STEP2: Add the CometChat and CometChatWidget CDN to our &lt;code&gt;html&lt;/code&gt; files
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In the &lt;em&gt;index.html&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Add the following CometChat and CometChatWidget  CDN to the &lt;code&gt;head&lt;/code&gt; tag just below the &lt;em&gt;firebase&lt;/em&gt; CDN:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
    &lt;span class="c"&gt;&amp;lt;!-- cometchat --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script
      &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;
      &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/@cometchat-pro/chat@2.3.1/CometChat.js"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script
      &lt;/span&gt;&lt;span class="na"&gt;defer&lt;/span&gt;
      &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://widget-js.cometchat.io/v2/cometchatwidget.js"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the body, just before the script tags, add the following line:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cometchat"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This is where the CometChat Widget will live. You will see that in a bit&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the &lt;em&gt;login.html&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Add the following CometChat and CometChatWidget  CDN to the &lt;code&gt;head&lt;/code&gt; tag just below the &lt;em&gt;firebase&lt;/em&gt; CDN:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
    &lt;span class="c"&gt;&amp;lt;!-- cometchat --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/@cometchat-pro/chat@2.3.1/CometChat.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script
      &lt;/span&gt;&lt;span class="na"&gt;defer&lt;/span&gt;
      &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://widget-js.cometchat.io/v2/cometchatwidget.js"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;We will move to &lt;code&gt;index.js&lt;/code&gt; file where all the remaining logic will happen. We will be focusing on the &lt;code&gt;init&lt;/code&gt; function&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;init&lt;/code&gt; function is used to check the authentication status of a user. If the user is authenticated, the user is redirected or allowed to stay on the &lt;em&gt;index.html&lt;/em&gt; page&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// User is signed in.&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;mainContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;else the user is redirected to the &lt;em&gt;login.html&lt;/em&gt; page.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// No user is signed in.&lt;/span&gt;
      &lt;span class="nx"&gt;mainContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;redirect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Now, our **CometChat&lt;/em&gt;* logic and &lt;strong&gt;create user&lt;/strong&gt; logic will live in the &lt;code&gt;if&lt;/code&gt; block above and the &lt;strong&gt;logout&lt;/strong&gt; logic will live in the &lt;code&gt;else&lt;/code&gt; block*&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Let's Continue!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  STEP 3: Add the CometChat &lt;strong&gt;Logout&lt;/strong&gt; Logic
&lt;/h2&gt;

&lt;p&gt;Enter the following code in the &lt;code&gt;else&lt;/code&gt; block just before &lt;code&gt;mainContainer.css("display", "none");&lt;/code&gt; line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;//Logout completed successfully&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logout completed successfully&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;//Logout failed with exception&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logout failed with exception:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;And that is all about the logout. It's that simple!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  STEP 4: Determine if a logged in user is a &lt;strong&gt;new&lt;/strong&gt; or &lt;strong&gt;returning&lt;/strong&gt; user
&lt;/h2&gt;

&lt;p&gt;Since the &lt;code&gt;login&lt;/code&gt; and &lt;code&gt;create user&lt;/code&gt; for our jQuery website isn't clearly separated, it is important to determine if the authenticated user is already existing on our CometChat User db. If the user is not yet registered on our CometChat User db, then we will add such user.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before we proceed collect the user details in the &lt;code&gt;if&lt;/code&gt; block of our &lt;code&gt;init&lt;/code&gt; function:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// user details&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To determine the authentication status of a user, enter the following code in the &lt;code&gt;if&lt;/code&gt; block of our &lt;code&gt;init&lt;/code&gt; function:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;UID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UID&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User details fetched for user:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// login and launch chat here in embedded mode&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User details fetching failed with error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// create new user, login and launch chat here docked mode&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;How will this code function?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;After checking for a user details, if the user exist, the &lt;code&gt;user&lt;/code&gt; block returns the user and we can &lt;code&gt;login the user and launch the chat widget here in embedded layout&lt;/code&gt;. If on the other hand, the user is new, the &lt;code&gt;error&lt;/code&gt; block will return no user and we will use that block to &lt;code&gt;create the new user, login and launch the chat widget here in docked layout&lt;/code&gt;. We will talk more about the layouts (&lt;code&gt;embedded&lt;/code&gt; and &lt;code&gt;docked&lt;/code&gt;) of displaying the chat widget in a bit&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We move!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  STEP 5: Add the CometChat &lt;strong&gt;Login&lt;/strong&gt; Logic
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;code&gt;response&lt;/code&gt; block add the following code to login the user:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;CometChatWidget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
              &lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User login successful:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User login failed with error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;//Check the reason for error and take appropriate action.&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Do not forget to replace &lt;code&gt;uid&lt;/code&gt; with your own details&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the login is successful, in the &lt;code&gt;then&lt;/code&gt; block, enter the following code to launch the CometChat widget:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;CometChatWidget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widgetID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WIDGET_ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#cometchat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;roundedCorners&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;height&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;600px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;800px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;defaultID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;superhero1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//default UID (user) or GUID (group) to show,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;defaultType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;//user or group&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Do not forget to replace &lt;code&gt;WIDGET_ID&lt;/code&gt; with your own details&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thumbs Up!!! You can now login an existing user into CometChat. They can also chat with the "friends" already existing in the database. &lt;/p&gt;

&lt;p&gt;We are proceeding to the &lt;em&gt;Create User&lt;/em&gt; logic&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  STEP 6: Add the CometChat &lt;strong&gt;Create User&lt;/strong&gt; Logic
&lt;/h2&gt;

&lt;p&gt;Now, let's get back to when we determined if a user already exist in &lt;strong&gt;STEP 4&lt;/strong&gt;. We want to work on the &lt;code&gt;error&lt;/code&gt; block (That is when the user do not already exist in our CometChat database).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the following code in the &lt;code&gt;error&lt;/code&gt; block to Create a new User:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userDisplayName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;CometChat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user created&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Do not forget to replace &lt;code&gt;apiKey&lt;/code&gt;, &lt;code&gt;uid&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; with your own details&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Having successfully created that user, let's login and launch the CometChat Widget in docked mode. Enter the following code in the &lt;code&gt;user&lt;/code&gt; block above:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;CometChatWidget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;CometChatWidget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widgetID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WIDGET_ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;docked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alignment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//left or right&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;roundedCorners&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;height&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;450px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;defaultID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;superhero1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//default UID (user) or GUID (group) to show,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;defaultType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;//user or group&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User login failed with error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;//Check the reason for error and take appropriate action.&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Do not forget to replace &lt;code&gt;WIDGET_ID&lt;/code&gt; and &lt;code&gt;uid&lt;/code&gt; with your own details&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That is it with the application!!! We can now register new users who are joining our app. Isn't that awesome?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Test the app and see for yourself. You can follow the progress of the test via your browser's console. See mine below:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;New User&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmit5y7s3begnyfsuycsh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmit5y7s3begnyfsuycsh.gif" alt="New User redirected to the docked view or mode after login" width="314" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Returning User&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sl0z45k2t8l9f604so7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sl0z45k2t8l9f604so7.gif" alt="New User redirected to the docked view or mode after login" width="385" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you check the users in your dashboard, you should see a new user added like mine below:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flu3vdko4mzp3fv0rw2o3.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flu3vdko4mzp3fv0rw2o3.JPG" alt="Alt Text" width="682" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Embedded Layout vs Docked Layout
&lt;/h2&gt;

&lt;p&gt;CometChat Widget can be displayed in styles. This can be done in two (2) ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Docked Layout&lt;/li&gt;
&lt;li&gt;Embedded Layout&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Docked Layout
&lt;/h3&gt;

&lt;p&gt;This is the floating chat that appears on the pages of a website. You will notice that a new user is redirected to such a chat when logged in for the first time to the app we just created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l826hazox01k44b24bb.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l826hazox01k44b24bb.JPG" alt="Docked Layout with a toggle button" width="583" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notice the toggle button used to remove or bring up the chat widget&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Embedded Layout
&lt;/h3&gt;

&lt;p&gt;The Embedded Layout is static. It is not toggled by a button like the Docked Layout. You will notice that a returning user is redirected to such a chat when logged in after the first time to the app we just created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feripacnjgswjqiehl6hs.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feripacnjgswjqiehl6hs.JPG" alt="Embedded Layout" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notice that it is embedded on the page and can't be toggled&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CometChat Widget Customization
&lt;/h2&gt;

&lt;p&gt;Let's now talk more about the chat widget. We created that widget so that we can control the chat on our website from our CometChat dashboard. So we will need to go back to the chat widget dashboard and see how to make some adjustments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F362w3251uy9t8ggi7das.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F362w3251uy9t8ggi7das.JPG" alt="Chat Widget sections for customization" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notice that we have switched from installation to customization in section &lt;code&gt;3&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where you customize the Chat widget to look and feel as you desire. The part labelled &lt;strong&gt;1&lt;/strong&gt; represent the &lt;strong&gt;sidebar and navigation&lt;/strong&gt; and the part labelled &lt;strong&gt;2&lt;/strong&gt; represent the &lt;strong&gt;main body&lt;/strong&gt; of the chat. When you click either of those sections, the settings are displayed in section &lt;strong&gt;3&lt;/strong&gt; (&lt;em&gt;Customization&lt;/em&gt;) and you can then make needed changes. There is also the &lt;strong&gt;general&lt;/strong&gt; settings - we can change the color of the toggle button for the docked chat layout there. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let's make a few changes to our chat widget&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Allow users to text chat each other

&lt;ol&gt;
&lt;li&gt;Click on the section &lt;strong&gt;2&lt;/strong&gt; of our chat widget&lt;/li&gt;
&lt;li&gt;Click on the customization tab in section &lt;strong&gt;3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Messages&lt;/em&gt; accordion tab&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Send a Message&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Turn on the &lt;code&gt;Enable&lt;/code&gt; button&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kcjpwkghizzvz80m4fd.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kcjpwkghizzvz80m4fd.JPG" alt="Enabling users to text chat each other" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow users to voice chat each other

&lt;ol&gt;
&lt;li&gt;Click on the section &lt;strong&gt;2&lt;/strong&gt; of our chat widget&lt;/li&gt;
&lt;li&gt;Click on the customization tab in section &lt;strong&gt;3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Photos, Videos &amp;amp; Files&lt;/em&gt; accordion tab&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Send Voice Notes&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Turn on the &lt;code&gt;Enable&lt;/code&gt; button&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8oz429uv92r7tg2hyfzi.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8oz429uv92r7tg2hyfzi.JPG" alt="Enabling users to voice chat each other" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow users to video call each other

&lt;ol&gt;
&lt;li&gt;Click on the section &lt;strong&gt;2&lt;/strong&gt; of our chat widget&lt;/li&gt;
&lt;li&gt;Click on the customization tab in section &lt;strong&gt;3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Photos, Videos &amp;amp; Files&lt;/em&gt; accordion tab&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Send Photos &amp;amp; Videos&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Turn on the &lt;code&gt;Enable&lt;/code&gt; button&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5iti76cou3dpl6hlz5k.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5iti76cou3dpl6hlz5k.JPG" alt="Enabling users to video call each other" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Group Chat

&lt;ol&gt;
&lt;li&gt;Click on the section &lt;strong&gt;2&lt;/strong&gt; of our chat widget&lt;/li&gt;
&lt;li&gt;Click on the customization tab in section &lt;strong&gt;3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;em&gt;Groups&lt;/em&gt; accordion tab&lt;/li&gt;
&lt;li&gt;Turn on all the buttons there&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqig2gbkey45h5lxxgggj.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqig2gbkey45h5lxxgggj.JPG" alt="Group Chat Customization" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Add CSS
&lt;/h1&gt;

&lt;p&gt;If you notice, our application is done but it is a bit off when it comes to styling. Let's make it more appealing with a bit of CSS. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a new file with the name: &lt;code&gt;style.css&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following code to the file&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Trebuchet MS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;'Lucida Sans Unicode'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;'Lucida Grande'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;'Lucida Sans'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* main container */&lt;/span&gt;
&lt;span class="nf"&gt;#main_container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#03A9F4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#main_container&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;letter-spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#main_container&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* cometchat */&lt;/span&gt;
&lt;span class="nf"&gt;#cometchat&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add the following line to the &lt;code&gt;head&lt;/code&gt; tag of the &lt;code&gt;html&lt;/code&gt; files
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="c"&gt;&amp;lt;!-- css --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Now our app looks like this:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnlljnioalmr7dtz9asp.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnlljnioalmr7dtz9asp.JPG" alt="jQuery Chat App with CSS" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Log in with 2 different accounts on different browsers and try the following:
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;User to User chat in action&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3x09kbyq3yaxzkru3kz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3x09kbyq3yaxzkru3kz.gif" alt="User to User chat in action" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Group Chat in action&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7nfwswjdkcuk767yjz5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7nfwswjdkcuk767yjz5.gif" alt="Group Chat in action" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating Group and adding members in action&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklndpn2y1w1q5yz899lc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklndpn2y1w1q5yz899lc.gif" alt="Creating Group and adding members in action" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How Awesome!!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I really feel like not concluding this tutorial but it is important that I let you explore the hidden treasures stored up in CometChat for developers. &lt;/p&gt;

&lt;p&gt;We were able to see how to create an account with CometChat, how to create a chat widget and integrate it into our jQuery website. We also went ahead to customize the chat widget to our taste and as a bonus, we styled our application to be even more appealing.&lt;/p&gt;

&lt;p&gt;I will indulge you to take out more time and re-visit the chat widget customization. You will notice that there are so many options we didn't explore together. Please play around with them and see what you can come up with.&lt;/p&gt;

&lt;p&gt;You can find the source code to jQuery Chat App we just built &lt;a href="https://github.com/EBEREGIT/jQuery-CometChat" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're considering expanding this chat app, here are a few resources to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cometchat.com/tutorials/build-a-jquery-php-powered-chat-app" rel="noopener noreferrer"&gt;Build a jQuery/PHP Powered Chat App&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cometchat.com/tutorials/jquery-chat-push-notifications" rel="noopener noreferrer"&gt;Add Push Notifications to your jQuery Chat App&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jquery</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>16 Thought-Provoking Resources for Developers</title>
      <dc:creator>kushal khandelwal</dc:creator>
      <pubDate>Fri, 28 May 2021 07:33:09 +0000</pubDate>
      <link>https://dev.to/cometchat/16-thought-provoking-resources-for-developers-10jn</link>
      <guid>https://dev.to/cometchat/16-thought-provoking-resources-for-developers-10jn</guid>
      <description>&lt;p&gt;Continued commitment to learning is one way developers can stay at the top of their game throughout their career. We all have our favorite resources (hello, Stack Overflow!) that we turn to time and time again, but sometimes, it’s good to switch it up and check out new material that offers fresh takes on the issues you’re dealing with as a web developer.&lt;/p&gt;

&lt;p&gt;Below we’re sharing a curated list for the dev community of the most interesting reads, podcasts and videos that have inspired us recently. Check it out, and then share any resources you’ve found insightful or helpful in the comments. &lt;/p&gt;

&lt;p&gt;Keeping in mind that information comes in different forms, this roundup has been divided into 3 categories - blogs, podcasts, and videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blog Posts
&lt;/h2&gt;

&lt;p&gt;These five blogs stood out for their creativity and resourcefulness. Some had amazing advice for developers and some managed to accumulate a lot of information for developers under one title.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Engineer to Engineer: Don't Be Afraid to Rock the Boat | Women Who Code
&lt;/h3&gt;

&lt;p&gt;This interview between Elizabeth Funk and Samantha Abbot goes beyond the code. They get in deep about being assertive in the workplace (especially as a woman) and asking for what is deserved. &lt;br&gt;
Samantha Abbot’s story about being a queer and female in a male-dominated industry is full of self-advocation, witty humor, self-affirmation, and dialogue on working in teams. This is a must-read for people anxiously trying to navigate the workplace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.womenwhocode.com/blog/engineer-to-engineer-don-t-be-afraid-to-rock-the-boat"&gt;Link to Article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Do You Need to Localize Your Website? | A List Apart
&lt;/h3&gt;

&lt;p&gt;This blog is published on a website with a niche for web developers. This piece is extremely useful for those trying to make difficult decisions on website localization. It is a great article for the polyglot web developer who needs to manage marketing, audience, and localization to help make a business successful. &lt;br&gt;
Full of personal anecdotes, there are plenty of tips that a web developer can take into account. For a piece discussing website localization, it was refreshing to read something that questions the need itself before diving into the specifics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.womenwhocode.com/blog/engineer-to-engineer-don-t-be-afraid-to-rock-the-boat"&gt;Link to Article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. The Purposes and Benefits of Cross-Functional Collaboration | .cult by Honeypot
&lt;/h3&gt;

&lt;p&gt;An article that captures the need of having interdisciplinary people work on the same project in the 21st century could not be written at a more opportune time. This piece communicates the benefits of intersectional teamwork in the developer’s world while keeping in mind the real work environment for the developer. &lt;br&gt;
As a developer in a managerial position, this piece will convince you of the need for versatile backgrounds in a developer team and even give you the step-by-step to make it happen. A great read for anyone trying to improve team collaboration in the workplace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cult.honeypot.io/reads/cross-functional-collaboration"&gt;Link to Article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4. So You Want to Use AI: Do You Build, or Do You Buy? | ReadWrite
&lt;/h3&gt;

&lt;p&gt;So You Want to Use AI is an adapted piece from the book “Real World AI.” Author Wilson Pang makes it clear that there is no one solution to problems when it comes to AI. This piece written by the CTO of a Silicon Valley firm was promising to begin with, and as the article progressed, Pang breaks down the process of working with AI in a company. &lt;br&gt;
The questions he poses here make for a proficient tool for any decision-maker. A great resource to check out before making any expensive decisions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://readwrite.com/2021/04/07/so-you-want-to-use-ai-do-you-build-or-do-you-buy/"&gt;Link to Article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Sex Doesn't Sell, GitHub Does | Hacker Noon
&lt;/h3&gt;

&lt;p&gt;If you’ve thought about the courage it takes for people to develop open-source software, this piece is exactly what you’re looking for. Marius, the author of this piece, manages to create an open discussion about the future of OSS and how licensing could very well be the only way for the developing world to continue to grow at big paces. This spins the story of paid software into an optimistic one and challenges people who want to retain free software in a very well thought-out manner.&lt;br&gt;
&lt;a href="https://hackernoon.com/sex-doesnt-sell-github-does-uou342x"&gt;Link to Article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  6. 25 Developer Blogs to Keep You at the Top of Your Game | CometChat Blog
&lt;/h3&gt;

&lt;p&gt;A blog that is a collection of all the best places for developers to find resources is a great resource in itself. Instead of scouring the internet for reliable sources, this article does that for you and gives you a good head-start on your self-growth calendar. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://comet.chat/5051"&gt;Link to Article&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Podcasts
&lt;/h2&gt;

&lt;p&gt;While there are plenty of podcasts out there that discuss coding, a select few manage to discuss solutions. As a problem-solver, knowing what tools you have available, be it in terms of new software, updates, or mental fortitude - these top 5 podcast episodes are a pleasure to listen to.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Software Engineering Radio - Episode 456: Tomer Shiran on Data Lakes
&lt;/h3&gt;

&lt;p&gt;This episode from the Software Engineering Radio is a discussion on Data Lakes, a new take on storing and processing data that exceeds beyond the data warehouse. With an industry expert, Tomer, this discussion manages to talk in-depth about the tools one would need to store, access, and analyze data from these lakes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/episode/7FmJGtVuLcmRzyqTYr0szQ?si=9d3fc74266e04f7a"&gt;Link to Episode&lt;/a&gt;&lt;br&gt;
&lt;iframe width="100%" height="232px" src="https://open.spotify.com/embed/episode/7FmJGtVuLcmRzyqTYr0szQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Developer Tea - Changing Work Environments and Availability Bias
&lt;/h3&gt;

&lt;p&gt;This entire podcast series is dedicated to providing clarity, perspective, and purpose to developers - no matter what stage of their career they’re in. During the pandemic, most developers were shifted to a WFH model, and that was followed by a very different workflow. This episode allows the developer to think differently about working from home and make it work for them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/episode/0KG7qnaSTE4DIfzGcvWzmu?si=820a7291b9464a34"&gt;Link to Episode&lt;/a&gt;&lt;br&gt;
&lt;iframe width="100%" height="232px" src="https://open.spotify.com/embed/episode/0KG7qnaSTE4DIfzGcvWzmu"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Software Daily - Makepath: Geospatial Technology with Brendan Collins
&lt;/h3&gt;

&lt;p&gt;This episode is a great rundown for an invaluable tool in the belt of a developer - working with geospatial libraries. The CEO of Makepath, a firm that helps other people in solving their problems by using geospatial technology talks about how people use it and why it’s so effective. With so much new in the field, their conversation provides specifics for problem-solving using geospatial data and still manages to make it easy to follow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/episode/6xKjBEvSgKtC371Iy1AP56?si=68-mBFcYQJ6ThOUVeNoxGA"&gt;Link to Episode&lt;/a&gt;&lt;br&gt;
&lt;iframe width="100%" height="232px" src="https://open.spotify.com/embed/episode/6xKjBEvSgKtC371Iy1AP56"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Changelog - Curl is a full-time job (and turns 23)
&lt;/h3&gt;

&lt;p&gt;This episode talks to developers of Client URL (curl), a project that to a certain degree, makes the internet what it is today. Daniel Stenberg talks about making his passion project into his full-time career and how that took place. The opportunities received and missed along the way and the future of library development shifting from C to Rust. This veteran developer has plenty of insight for everyone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/episode/4nGvM2Y9PND8MdcAkToDdD?si=xESx_LhUQV6OUsxL8Lc6QQ"&gt;Link to Episode&lt;/a&gt;&lt;br&gt;
&lt;iframe width="100%" height="232px" src="https://open.spotify.com/embed/episode/4nGvM2Y9PND8MdcAkToDdD"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Fragmented: The Software Podcast  - 208: Developing Software at Startups with Jason Roberts
&lt;/h3&gt;

&lt;p&gt;The most entertaining of this list, this episode takes us through the struggles of a start-up developer. From almost becoming a billionaire to awkward parties full of developers, this conversation is full of tidbits that make you smile. The conversation is light and is perfect for anyone who wants to listen about the very interesting life of Jason Roberts (the almost-CTO of uber).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/episode/2M2gI3QdCocZeQIY7b9epc?si=7fa30517383f43a4"&gt;Link to Episode&lt;/a&gt;&lt;br&gt;
&lt;iframe width="100%" height="232px" src="https://open.spotify.com/embed/episode/2M2gI3QdCocZeQIY7b9epc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  YouTube Videos
&lt;/h2&gt;

&lt;p&gt;YouTube is an all-familiar place for developers, after all, free tutorials and code-along for the public are invaluable to anyone learning how to code, or expanding their skillset. While several folks make videos about coding on YouTube, not many can boast the quality and entertainment that the videos on this list provide. The videos in this list go above and beyond just coding, and actually create content that a developer can relate to. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. The KEY To Thinking Like a Programmer (Fix This Or Keep Struggling)
&lt;/h3&gt;

&lt;p&gt;This video is great for anyone who feels like they’re facing imposter syndrome. For veteran developers, this video will most likely re-assure them of their skills, and for newbie developers, it will give them a strong footing. A well-put video for all kinds of developers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCZ9qFEC82qM6Pk-54Q4TVWA"&gt;Link to Channel&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vrmKwQ-JPTA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Build a Music Player | Vanilla JavaScript - YouTube
&lt;/h3&gt;

&lt;p&gt;If you’re looking for a side project to do with any extra time you have because of WFH, this video is definitely worth the watch. Traversy Media makes JavaScript look simple and that is a talent in itself. At the end of this video, you’ll build an aesthetically pleasing media player with HTML, JavaScript, and CSS. The final product of this project is so good, it secured a spot in our top 5 tech videos for April.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/TraversyMedia"&gt;Link to Channel&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QTHRWGn_sJw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  3. I Built a Trading Bot to let Subscribers Trade my $25,000 on Twitch
&lt;/h3&gt;

&lt;p&gt;This video is both chaotic and entertaining at the same time. For someone who wants to get ‘close’ to their subscribers, Joma really invested a lot of money to do it. A share trading bot that runs through twitch commands may seem like an eccentric project, but before you judge it, watch it for yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/JomaOppa/featured"&gt;Link to Channel&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-UdWguw90g4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Create a Fantastic BOUNCY Line with SVG &amp;amp; JS!
&lt;/h3&gt;

&lt;p&gt;A video that explains how to code and design a bouncy line is perfect for anyone who wants to wet their hands with some robust design principles and obscure designing. Learning to use SVG and JS together is an added bonus to this very fun project that makes it a must-watch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/DesignCourse/featured"&gt;Link To Channel&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/W1GEr61Bm08"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The Most Productive Developers Of All Time
&lt;/h3&gt;

&lt;p&gt;A video that talks about 4 people who changed the world and made billions with their keyboard? Sign me up! As a developer wanting to improve productivity and code more every day, this video will inspire you to do more and tell you some intriguing facts along the way. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/AaronJack/featured"&gt;Link to Channel&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/KnAEIEnnvAQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  6. How to Create a Chat App with React in 30 Mins
&lt;/h3&gt;

&lt;p&gt;With almost every company wanting to add text, voice or video calling in their apps,  communication tech is at its peak right now. Developer Eddie Jaoude walks us through how to create chat in React using &lt;a href="https://comet.chat/3cb1"&gt;CometChat's React Chat UI Kit&lt;/a&gt;.&lt;br&gt;
It's insanely simple to build, allows for some really cool customization, comes with loads of features right out of the box, and only takes about 30 minutes to implement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCWu7LtG16A9ZgcyBpNMCX0Q"&gt;Link to Channel&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_RI6ye-fTUc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;What developer resources are you digging right now? Share in comments below! &lt;/p&gt;

</description>
      <category>learning</category>
      <category>discuss</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>SwiftUI Architecture: Observable Objects, the Environment and Combine</title>
      <dc:creator>marinbenc🐧</dc:creator>
      <pubDate>Tue, 11 Feb 2020 07:53:03 +0000</pubDate>
      <link>https://dev.to/cometchat/swiftui-course-part-6-swiftui-architecture-observable-objects-the-environment-and-combine-5hb4</link>
      <guid>https://dev.to/cometchat/swiftui-course-part-6-swiftui-architecture-observable-objects-the-environment-and-combine-5hb4</guid>
      <description>&lt;p&gt;By now you already have a good understanding of how SwiftUI views work. You create a state variable and a &lt;code&gt;body&lt;/code&gt; computed variable that spits out a view based on that state. Whenever the state changes, SwiftUI calls &lt;code&gt;body&lt;/code&gt; and updates what's on the screen.&lt;/p&gt;

&lt;p&gt;This paradigm works incredibly well, but there are some special cases in this paradigm that need extra care. One of those cases is when you want to &lt;strong&gt;share a piece of state between two views&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are a couple of ways to share state in SwiftUI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pass the current value of the state in the initializer.&lt;/li&gt;
&lt;li&gt;Use a binding.&lt;/li&gt;
&lt;li&gt;Use observable environment objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this part of the SwiftUI course, you'll take a look at these ways to share data. You'll get an understanding of when and how to share data, as well as the advantages and disadvantages of these three approaches.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As always, you can find a link to the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat" rel="noopener noreferrer"&gt;finished project code on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sharing data with View children and stateless Views
&lt;/h2&gt;

&lt;p&gt;First, let's take a look at the simplest possible way to share data: Passing it in the initializer of a view. You already used the pattern when you created the &lt;code&gt;AvatarView&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;

&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isOnline&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="kt"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You gave &lt;code&gt;AvatarView&lt;/code&gt; a property called &lt;code&gt;isOnline&lt;/code&gt; that you pass in its initializer. You made the online indicator green or gray based on this property.&lt;/p&gt;

&lt;p&gt;You later called this initializer from &lt;code&gt;ContactRow&lt;/code&gt; with a value of whether the user is online or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because SwiftUI is reactive, whenever the contact's status changes to offline, SwiftUI will know to rebuild the avatar view with the new value.&lt;/p&gt;

&lt;p&gt;This isn't anything fancy, it's just plain old Swift initializers. That's the biggest advantage of this approach: Simplicity. Here, &lt;code&gt;AvatarView&lt;/code&gt; has no state, all properties are marked with &lt;code&gt;let&lt;/code&gt;, which means it's &lt;strong&gt;completely immutable&lt;/strong&gt;. Instead of responding to state changes, it will be rebuilt when the state changes. This type of immutable view has different names in different reactive frameworks: functional, stateless... dumb. (Yes, dumb.)&lt;/p&gt;

&lt;p&gt;Using stateless views has a lot of advantages. For starters, they're simple. You don't have to track or debug state changes. You can easily preview and test the view without having to modify its state. Stateless views are decoupled from your frameworks and libraries, whether it's networking with Alamofire or a database framework like Core Data. They're easy to reuse and even copy and paste to different parts of the app or entirely different projects.&lt;/p&gt;

&lt;p&gt;As you can see, &lt;em&gt;statelessness is a good thing&lt;/em&gt;. You can't always use this pattern, though. To pass state into the initializer, you need to be the view &lt;em&gt;creating&lt;/em&gt; the stateless view. If you think of the view hierarchy as a tree, passing state in the initializer is only possible to the view's &lt;em&gt;direct children&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyfju46a9bz5bhx1g26p7.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyfju46a9bz5bhx1g26p7.png" alt="Passing data through the initializer in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think hard about whether a view needs to track its internal state variables or if you can get away with passing the state in the initializer. Try to use stateless views as much as you can.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am creating this course in collaboration with CometChat, a modern chat platform to help you add chat to you Swift app. During the next few weeks, we’ll be releasing installments of our free SwiftUI course here on dev.to! In the course, you’ll dive deep into SwiftUI by building a real-world production-scale chat app, learning SwiftUI in a practical way, on a scale larger than a simple example app. Follow me to get notified of future parts of this course! You can also follow &lt;a href="https://twitter.com/cometchat" rel="noopener noreferrer"&gt;@CometChat&lt;/a&gt; on Twitter see the course of &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com" rel="noopener noreferrer"&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%2Favpunu4hqp1ut7enf5tq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using &lt;code&gt;Binding&lt;/code&gt; for two-way data sharing between a view and its children
&lt;/h2&gt;

&lt;p&gt;In families, just like in SwiftUI, parents are usually the ones telling kids the state of the world. Sometimes, however, your dad might not know how to install Viber to call your uncle. In that case, you're the one passing information to your parents.&lt;/p&gt;

&lt;p&gt;This happens in SwiftUI too. Passing data in the initializer is great if you want to pass data to the view's children. If you want the reverse, however, you need a &lt;strong&gt;binding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Bindings enable two-way communication between your views. They're usually used with &lt;strong&gt;interactive views&lt;/strong&gt; like text fields, toggles, checkboxes and similar. They allow two views to share a single piece of state.&lt;/p&gt;

&lt;p&gt;For instance, when you created &lt;code&gt;ErrorTextField&lt;/code&gt;, you used a binding to a &lt;code&gt;String&lt;/code&gt; instead of a state variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Binding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, you initialized this view in the login screen by passing it the binding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;LoginView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, the &lt;code&gt;$&lt;/code&gt; operator converted a &lt;em&gt;state&lt;/em&gt; to a &lt;em&gt;binding&lt;/em&gt;. A binding is a kind of pointer to a piece of state. &lt;code&gt;LoginView&lt;/code&gt; owns the state, but by giving &lt;code&gt;ErrorTextField&lt;/code&gt; a binding to that state, it lets the text field change the value of the state.&lt;/p&gt;

&lt;p&gt;This means that both &lt;code&gt;LoginView&lt;/code&gt; and &lt;code&gt;ErrorTextField&lt;/code&gt; can change the value of the email, and both will always update to match the latest value.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fogpfoiv8k19rtjn1gzm5.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fogpfoiv8k19rtjn1gzm5.png" alt="Using a Binding to share data between two SwiftUI views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Passing bindings, just like passing the state values directly, is used when you want to share state between a parent view and its direct children. As opposed to passing state values, though, a &lt;em&gt;binding adds statefulness to the component&lt;/em&gt;, making it more complex to read, write, test and preview. Keep that in mind when using this approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharing data between unrelated views
&lt;/h2&gt;

&lt;p&gt;The above two ways of sharing data have all been between two directly linked views. Sometimes, you want to share data between two unrelated screens. For instance, the currently logged in user is shared between the feed, the settings screen and the profile screen. Or, there might be a registration flow with multiple screens that stores the data of each screen at a shared location.&lt;/p&gt;

&lt;p&gt;One way to do this is to use bindings or passing the user directly to child views. The disadvantage of that approach is that it's far too cumbersome. You'd have to pass the user to each child separately. For any change that one of the child views make, you'd have to roll back up to the main view to update the user, and then propagate back down the hierarchy so all views update.&lt;/p&gt;

&lt;p&gt;Instead, it's much easier to have a single place where the user is stored. Whenever any view changes the user, all other views update instantly. &lt;/p&gt;

&lt;p&gt;You can do this type of &lt;strong&gt;global state sharing&lt;/strong&gt; using a combination of Combine and SwiftUI features: &lt;strong&gt;Observable objects and environment objects.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Combine's Observable Objects in SwiftUI
&lt;/h3&gt;

&lt;p&gt;Even though this is a SwiftUI course, we'll take a brief detour and talk a little about Combine. Combine is a Swift framework that enables you to track changes to some value over time. Instead of using a plain &lt;code&gt;String&lt;/code&gt;, Combine gives you a &lt;code&gt;Publisher&lt;/code&gt; that emits a series of strings over time. If you're familiar with RxSwift or ReactiveCocoa, Combine does the same thing, but it's built into Swift.&lt;/p&gt;

&lt;p&gt;SwiftUI uses Combine to track changes to state variables. While you might see the email as a &lt;code&gt;String&lt;/code&gt;, SwiftUI sees it as a series of different string values over time. Using Combine, it can listen for changes to the value and update the view accordingly.&lt;/p&gt;

&lt;p&gt;You can do the same thing SwiftUI does by using Combine's &lt;code&gt;ObservableObject&lt;/code&gt; to track changes to any value, whether it's in a &lt;code&gt;View&lt;/code&gt; or an entirely different object. &lt;code&gt;ObservableObject&lt;/code&gt; object tracks changes to its properties and publishes a Combine event whenever a change occurs.&lt;/p&gt;

&lt;p&gt;Let's create a new observable object to track the currently logged in user. Create a new plain Swift file and name it &lt;strong&gt;AppStore.swift&lt;/strong&gt;. No, you're not building the iOS &lt;em&gt;App Store&lt;/em&gt;, instead, you're making a shared storage location for different views in your app.&lt;/p&gt;

&lt;p&gt;Add the following class to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Combine&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;AppStore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;AppState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;@Published&lt;/span&gt; &lt;span class="kd"&gt;private(set)&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;AppState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;setCurrentUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, you import both Combine and SwiftUI. Then, you declare a class that conforms to the &lt;code&gt;ObservableObject&lt;/code&gt; protocol. Inside the class, you write a nested struct that will hold the current user and create a property of that type.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ObservableObject&lt;/code&gt; protocol has one requirement: &lt;code&gt;objectWillChange&lt;/code&gt;. This is a Combine &lt;code&gt;Publisher&lt;/code&gt;, an object that fires a series of events whenever the &lt;em&gt;observed object&lt;/em&gt; changes. Thankfully, you don't have to implement this yourself.&lt;/p&gt;

&lt;p&gt;By marking &lt;code&gt;state&lt;/code&gt; with &lt;code&gt;@Published&lt;/code&gt;, you tell Combine to automatically generate an implementation of &lt;code&gt;objectWillChange&lt;/code&gt; that tracks changes to &lt;code&gt;state&lt;/code&gt; and publishes an event whenever you change the state. Thanks, Combine!&lt;/p&gt;

&lt;p&gt;You also mark the property with &lt;code&gt;private(set)&lt;/code&gt;. If you haven't seen this before, this is an access control modifier in Swift that makes the property &lt;em&gt;private for modification&lt;/em&gt;, but &lt;em&gt;public for access&lt;/em&gt;. This means that everyone can &lt;em&gt;read&lt;/em&gt; &lt;code&gt;state&lt;/code&gt;, but only &lt;code&gt;AppStore&lt;/code&gt; can &lt;em&gt;change&lt;/em&gt; the state. This is just an insurance policy: When dealing with shared state, it's always a good idea to limit how other objects can change that state.&lt;/p&gt;

&lt;p&gt;Finally, you add a method that lets users of this class change the state by setting a new user. Whenever this method is called, &lt;code&gt;currentUser&lt;/code&gt; is changed, and &lt;code&gt;AppStore&lt;/code&gt; publishes an event telling everyone that's listening that the state has changed.&lt;/p&gt;

&lt;p&gt;For instance, a profile screen could listen to these changes and update the user it's showing when a new one is set. Since you can have multiple listeners, different unrelated views can be updated all at once whenever &lt;code&gt;AppState&lt;/code&gt; changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Observable Objects to the Environment in SwiftUI
&lt;/h2&gt;

&lt;p&gt;Writing the observable object is only one part of the equation, though. You still need a way to create the object and share it with different views in your app. You'll do this using SwiftUI's &lt;strong&gt;Environment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each view and all of its children exist in an environment. The environment is a shared pool of floating objects and values that the view or any of its children can grab and use at any time.&lt;/p&gt;

&lt;p&gt;You'll add an instance of &lt;code&gt;AppStore&lt;/code&gt; to the environment of your root view. This will enable any view in your app to grab the store and its data.&lt;/p&gt;

&lt;p&gt;Remember, the &lt;code&gt;SceneDelegate&lt;/code&gt; is where you create your root view, so open &lt;strong&gt;SceneDelegate.swift&lt;/strong&gt; and add a new property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;AppStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the store you'll add to the environment. Since you need to add it to your root component, call the &lt;code&gt;environmentObject&lt;/code&gt; method on the &lt;code&gt;contentView&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;contentView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NavigationView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;WelcomeView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;environmentObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add the store to the environment.&lt;/p&gt;

&lt;p&gt;Now that the store is in there, it's time to fetch it from different views in your app. Start by opening &lt;strong&gt;LoginView.swift&lt;/strong&gt;. Add the following property to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@EnvironmentObject&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;AppStore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By declaring the property an &lt;code&gt;@EnvironmentObject&lt;/code&gt;, you tell SwiftUI to automatically look for an object of that type in the environment. No need to manually instantiate or look for it!&lt;/p&gt;

&lt;p&gt;At the bottom of &lt;code&gt;login&lt;/code&gt;, add a line to save a new user in the store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCurrentUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a user logs in, they will get saved in the app store. This same app store is shared with other views, which will update automatically. One of those is &lt;code&gt;ContactsView&lt;/code&gt;: Open &lt;strong&gt;ContactsView.swift&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of hard-coding a user, you'll change the view to grab the user in the app store. First, fetch the store the same way you did for &lt;code&gt;LoginView&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@EnvironmentObject&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;AppStore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, inside &lt;code&gt;body&lt;/code&gt;, replace the &lt;code&gt;ForEach&lt;/code&gt; block with a &lt;code&gt;ZStack&lt;/code&gt; of the contact row and a navigation link to the chat screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="c1"&gt;// New code from here&lt;/span&gt;
    &lt;span class="kt"&gt;ZStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

      &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;currentUser&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="kt"&gt;NavigationLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ChatView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nv"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kt"&gt;EmptyView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;shadow&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRowInsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EdgeInsets&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="c1"&gt;// ... to here&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigationBarTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Contacts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might be confused by the use of &lt;code&gt;map&lt;/code&gt;. &lt;code&gt;store.state.currentUser&lt;/code&gt; is optional, so you need to unwrap it before you can use it. However, writing &lt;code&gt;if let&lt;/code&gt; inside a body will result in a compiler error because Swift will get confused about what kind of view you're trying to make. To get around this, you can use &lt;code&gt;map&lt;/code&gt; on the optional. It will work the same way as &lt;code&gt;if let&lt;/code&gt;: The function passed to &lt;code&gt;map&lt;/code&gt; will only get called if the optional is not &lt;code&gt;nil&lt;/code&gt;. If the current user is &lt;code&gt;nil&lt;/code&gt;, the function won't get called, and no navigation link will get created.&lt;/p&gt;

&lt;p&gt;Build and run the project now.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9jhukzoyhfsiq1p7wa6b.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9jhukzoyhfsiq1p7wa6b.gif" alt="Navigating to a detail View from a SwiftUI List"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You now have the app store, an observable object, inside the environment. When you log in, the view will update the store in the environment with a new user. Since the store is an observable object, all other views will get notified of the change. This includes &lt;code&gt;ContactView&lt;/code&gt;, which will use the currently logged in user to create a chat screen.&lt;/p&gt;

&lt;p&gt;Sharing data like this is perfect for &lt;strong&gt;global state&lt;/strong&gt; of your app, like the currently logged in user, whether or not the user is logged in, does the user have a premium or regular account and other app-level data.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use which approach
&lt;/h2&gt;

&lt;p&gt;Stateless views, bindings, environment objects... All of these approaches have advantages and disadvantages and should be used at different times. To give you a better understanding of when to use which, I prepared a little cheat sheet. Don't worry, I won't take your exam away for using it!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzi6ztzbvoqe1eablfsph.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzi6ztzbvoqe1eablfsph.png" alt="SwiftUI Architecture Cheat Sheet: A diagram of different ways to pass data between SwiftUI views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Combine to track the keyboard height
&lt;/h2&gt;

&lt;p&gt;Run your app and navigate to the chat screen. When you start typing your message, you'll see the keyboard appear. Only, it appears &lt;em&gt;on top&lt;/em&gt; of the text field, so you can't even see what you're typing! That's no good. Let's dive further into Combine with another use case for observable objects: Observing the keyboard.&lt;/p&gt;

&lt;p&gt;You'll fix this issue by creating an observable object that will listen to &lt;code&gt;NotificationCenter&lt;/code&gt; notifications for changes to the keyboard's height. As the keyboard rises or falls, you'll publish events to everyone that's listening.&lt;/p&gt;

&lt;p&gt;You'll listen to this event in the chat screen. When the keyboard pops up, you'll increase the padding of the text field so that it's always above the keyboard.&lt;/p&gt;

&lt;p&gt;Create a new plain Swift file and call it &lt;strong&gt;KeyboardObserver.swift&lt;/strong&gt;. Add a new &lt;code&gt;ObservableObject&lt;/code&gt; class to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Combine&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;KeyboardObserver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ObservableObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;@Published&lt;/span&gt; &lt;span class="kd"&gt;private(set)&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;keyboardHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like earlier, you use &lt;code&gt;@Published&lt;/code&gt; to automatically publish events whenever that value changes.&lt;/p&gt;

&lt;p&gt;You'll update the height based on two notifications: &lt;code&gt;keyboardWillShowNotification&lt;/code&gt; and &lt;code&gt;keyboardWillHideNotification&lt;/code&gt;. Notification Center has Combine extensions that use Publishers instead of manually subscribing to the notification. Add the following property to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;keyboardWillShow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NotificationCenter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIResponder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardWillShowNotification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compactMap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userInfo&lt;/span&gt;&lt;span class="p"&gt;?[&lt;/span&gt;&lt;span class="kt"&gt;UIResponder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardFrameEndUserInfoKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;CGRect&lt;/span&gt;&lt;span class="p"&gt;)?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You call &lt;code&gt;publisher(for:)&lt;/code&gt; on the default Notification Center to get a publisher that emits that notification's events. Remember, Combine lets you deal with streams of values over time. These streams, just like arrays, are &lt;em&gt;collections&lt;/em&gt;. This means that all of the collection methods you're used to, like &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;compactMap&lt;/code&gt; and others, are already there. In the above example, you use &lt;code&gt;compactMap&lt;/code&gt; to get a value from the &lt;code&gt;userInfo&lt;/code&gt; of the notification that corresponds to the keyboard's height. This makes &lt;code&gt;keyboardWillShow&lt;/code&gt; a stream of &lt;code&gt;CGFloat&lt;/code&gt; values over time.&lt;/p&gt;

&lt;p&gt;Next, you'll add another property that tracks when the keyboard hides. Add it below the one you just created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;keyboardWillHide&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NotificationCenter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIResponder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardWillHideNotification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever you receive a notification that the keyboard has hidden, you'll convert that notification to a &lt;code&gt;CGFloat&lt;/code&gt; of &lt;code&gt;0&lt;/code&gt;, since a hidden keyboard has no height. Essentially, &lt;code&gt;keyboardWillHide&lt;/code&gt; is a stream of zeros.&lt;/p&gt;

&lt;p&gt;Now that you are publishing events for those two notifications, it's time to &lt;em&gt;merge&lt;/em&gt; them together to update the keyboard height property. Add the following initializer to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Publishers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyboardWillShow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keyboardWillHide&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;RunLoop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;keyboardWillShow&lt;/code&gt; and &lt;code&gt;keyboardWillHide&lt;/code&gt; are both Publishers. Publishers emit values. To listen and respond to those values, you have to &lt;em&gt;subscribe&lt;/em&gt; to the publishers. Subscribing allows you to call a function or closure (using the &lt;code&gt;sink&lt;/code&gt; method), or update a value whenever a Publisher emits a new event (using &lt;code&gt;assign(to:on:)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In the above case, you first merge the two publishers into one. That way, you'll get the keyboard's height when it raises and a zero when it falls. You'll subscribe to the new publisher on the main thread because it's responsible for updating the UI. By calling &lt;code&gt;assign&lt;/code&gt;, you tell Combine to set &lt;code&gt;keyboardHeight&lt;/code&gt; whenever to whichever value the Publisher emits.&lt;/p&gt;

&lt;p&gt;At this point, you'll get a warning that the result of &lt;code&gt;assign&lt;/code&gt; is unused. This is because &lt;code&gt;assign&lt;/code&gt; returns a &lt;strong&gt;cancellable&lt;/strong&gt; that you're not using. A cancellable doesn't do much, it's more of a reference to the subscription. If you used Notification Center, you might remember that you need to eventually remove observers to avoid memory loops. The same is true for Combine: If you don't remove subscriptions from &lt;code&gt;KeyboardObserver&lt;/code&gt;, it will never get deallocated.&lt;/p&gt;

&lt;p&gt;If you store the cancellable in a property of the class, the cancellable will get deallocated when the class does. Upon deallocation, the cancellable automatically destroys the subscription, removing all reference cycles that were created and letting the object die peacefully, as opposed to going on forever as a zombie.&lt;/p&gt;

&lt;p&gt;Add a new property to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;cancellables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;AnyCancellable&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;code&gt;Set&lt;/code&gt; which will house all of your cancellables for this class. &lt;/p&gt;

&lt;p&gt;Next, add the following line to the bottom of &lt;code&gt;init&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cancellable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method will store the cancellable in the set. No more warnings, no more memory leaks!&lt;/p&gt;

&lt;p&gt;Now that you have the keyboard observer, it's time to use it &lt;strong&gt;ChatView.swift&lt;/strong&gt;. Open the file and add a new property to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@ObservedObject&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;keyboardObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;KeyboardObserver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using &lt;code&gt;@ObservedObject&lt;/code&gt; you tell SwiftUI to update the UI whenever the object changes. Next, use the observer to grab the keyboard's height in &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;ZStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;edgesIgnoringSafeArea&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;ChatTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sendAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;onSendTapped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// These two lines are new:&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keyboardObserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;easeInOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigationBarTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the keyboard pops up, you'll raise the text field by the height of the keyboard. Since everything is in a &lt;code&gt;VStack&lt;/code&gt;, the &lt;code&gt;List&lt;/code&gt; will get shorter automatically. You'll also animate this change by calling &lt;code&gt;animation&lt;/code&gt; after &lt;code&gt;padding&lt;/code&gt;. SwiftUI will calculate the to and from values to animate without you having to do anything. Pretty neat, right?&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9tg66bwv03kl8u5mj6e2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9tg66bwv03kl8u5mj6e2.gif" alt="Handle keyboard rising in SwiftUI using Combine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the project and navigate to the chat screen. As you start typing, you'll see the keyboard pop up and the text field raises to match it. Now you can &lt;em&gt;see&lt;/em&gt; what you're typing.&lt;/p&gt;

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

&lt;p&gt;You are now almost done with your chat app! In this section of the SwiftUI course, you went one step further from static, hard-coded values. You used initializers, bindings and observable objects to pass data between your views and breathe a bit of life into your app.&lt;/p&gt;

&lt;p&gt;You learned that passing data in the initializer is the simplest way to give a bit of state to a direct child of a view. You also learned that you can use bindings for two-way communication between a child and its parent. Using environment objects, you added global state to your app that any view can access. Finally, using Combine you converted a Notification Center notification into an observable object that updates the UI. All in a day's work, right?&lt;/p&gt;

&lt;p&gt;Now that you have an understanding of how to deal with data, there's only one final step: Getting the data. The next section of the SwiftUI course deals with connecting everything up to CometChat, a chat SDK that will let you send and receive messages over the Internet. Keep reading to see your app come to life!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
    </item>
    <item>
      <title>Creating a chat screen in SwiftUI</title>
      <dc:creator>marinbenc🐧</dc:creator>
      <pubDate>Tue, 11 Feb 2020 07:52:42 +0000</pubDate>
      <link>https://dev.to/cometchat/swiftui-course-part-5-making-a-chat-screen-in-swiftui-lhe</link>
      <guid>https://dev.to/cometchat/swiftui-course-part-5-making-a-chat-screen-in-swiftui-lhe</guid>
      <description>&lt;p&gt;A chat app wouldn't be a chat app without a chat screen. In this part of the SwiftUI course, you'll put everything you've learned so far together, and build a cool looking chat screen.&lt;/p&gt;

&lt;p&gt;Here's what you'll build:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff0v3rzatohdzv9hhikzb.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff0v3rzatohdzv9hhikzb.png" alt="Making a SwiftUI chat screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The chat screen consists of two main views: a list of messages and a text field. Each message contains the user's avatar and a text bubble displaying the message. The text area holds a text field and a send button side-by-side.&lt;/p&gt;

&lt;p&gt;Looking at this screen, it might seem like a daunting task to build it. Don't worry! We'll tackle it piece-by-piece. Once you put those pieces together, you'll be surprised at how great everything turned out! Let's get going.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As always, you can find a link to the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat" rel="noopener noreferrer"&gt;finished project code on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Modifying the avatar
&lt;/h2&gt;

&lt;p&gt;Earlier in the course, you created an avatar view that you can reuse across your app. Now, it's time to reap the benefits of that investment. Instead of recreating a whole new view, you'll slightly tweak the avatar view to fit the needs of the chat message rows.&lt;/p&gt;

&lt;p&gt;You'll change the avatar view so that the online indicator can be hidden. Open &lt;strong&gt;AvatarView.swift&lt;/strong&gt; and add a new property to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;showsOnlineStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll use this variable to determine whether or not the online badge will be shown. Set this property to &lt;code&gt;true&lt;/code&gt; at the bottom of a new initializer that you'll add to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isOnline&lt;/span&gt;
  &lt;span class="n"&gt;showsOnlineStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add another initializer to the class, this time without &lt;code&gt;isOnline&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="n"&gt;showsOnlineStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will call this initializer when you don't need to know if the user is online or not.&lt;/p&gt;

&lt;p&gt;Finally, make a few changes to &lt;code&gt;body&lt;/code&gt; to only show the online badge if &lt;code&gt;showsOnlineStatus&lt;/code&gt; is set to &lt;code&gt;true&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;ZStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"avatar_placeholder0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Wrap the Circle in an if block:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;showsOnlineStatus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that in place, you can get started on creating the message item.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am creating this course in collaboration with CometChat, a modern chat platform to help you add chat to you Swift app. During the next few weeks, we’ll be releasing installments of our free SwiftUI course here on dev.to! In the course, you’ll dive deep into SwiftUI by building a real-world production-scale chat app, learning SwiftUI in a practical way, on a scale larger than a simple example app. Follow me to get notified of future parts of this course! You can also follow &lt;a href="https://twitter.com/cometchat" rel="noopener noreferrer"&gt;@CometChat&lt;/a&gt; on Twitter see the course of &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com" rel="noopener noreferrer"&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%2Favpunu4hqp1ut7enf5tq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the view for chat messages
&lt;/h2&gt;

&lt;p&gt;By the end of this section, you'll create a view that shows each message the user sends or receives.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxa969xig0h45fyfj1sw9.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxa969xig0h45fyfj1sw9.png" alt="Making a SwiftUI chat screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a user sends a message, it will have a blue background and be aligned to the right. If the user receives a message, it will have a white background and come from the left. When you receive or send a couple of messages, only the last one of those will show the avatar. Let's get started!&lt;/p&gt;

&lt;p&gt;First, you'll create a new model struct for you messages. Crate a new plain Swift file and name it &lt;strong&gt;Message.swift&lt;/strong&gt;. Add the following to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Identifiable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like &lt;code&gt;Contact&lt;/code&gt;, you'll make &lt;code&gt;Message&lt;/code&gt; identifiable, so that you can later display it in a list view. Now you can start creating the view that shows this message.&lt;/p&gt;

&lt;p&gt;Create a new SwiftUI view file and name it &lt;strong&gt;ChatMessageRow.swift&lt;/strong&gt;. Change the struct to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ChatMessageRow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Message&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;isLastFromContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The struct has three properties. One is the message you'd like to show. The second property determines if the message is incoming or if it was sent out from the currently logged in user. The final property determines if this message was last in a list of multiple messages from a single contact.&lt;/p&gt;

&lt;p&gt;[TODO: Screenshot]&lt;/p&gt;

&lt;p&gt;The latter two properties will determine the look of this view.&lt;/p&gt;

&lt;h3&gt;
  
  
  Displaying the content of the message
&lt;/h3&gt;

&lt;p&gt;Instead of having a 300-lines-long &lt;code&gt;body&lt;/code&gt; behemoth, you'll make this view piece by piece. You'll create a few computed variables where you'll return parts of the view and then combine those parts in &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first part will be the most important part of a message: the content. Add the following computed property to the bottom of the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like &lt;code&gt;body&lt;/code&gt;, you can create computed properties that return &lt;code&gt;some View&lt;/code&gt;, and use this pattern to clean up your code so that it's more readable. For now, the text is a simple &lt;code&gt;Text&lt;/code&gt; with some padding and styling applied.&lt;/p&gt;

&lt;p&gt;Next, fill up &lt;code&gt;body&lt;/code&gt; with a horizontal stack containing the avatar view and the text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alongside the two views in the stack, you add a spacer so that everything is aligned to the left. By setting the stack's alignment to &lt;code&gt;.bottom&lt;/code&gt;, you make sure the items start at the bottom of the stack.&lt;/p&gt;

&lt;p&gt;Before I show you what this looks like, let's modify the preview a bit. Scroll down to the &lt;code&gt;PreviewProvider&lt;/code&gt; and add the following property to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;chatMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hashValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pellentesque ipsum. Mauris elem enes tumen mauris vitae tortor. Pellentesque ipsum."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a dummy message that you'll use to preview the view. Next, modify &lt;code&gt;previews&lt;/code&gt; to show three different permutations of what your view can look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ChatMessageRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chatMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isLastFromContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="kt"&gt;ChatMessageRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chatMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isLastFromContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="kt"&gt;ChatMessageRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chatMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isLastFromContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You create one outgoing, one incoming, and one message row where the message is not the last message from that contact. Take a look at the preview to see your work so far:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F45i78xpyc2oecichave2.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F45i78xpyc2oecichave2.png" alt="Creating the message item of a SwiftUI chat UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's a good start! You're showing the avatar and the message, but you're missing the bubble around the message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Showing a chat bubble
&lt;/h3&gt;

&lt;p&gt;To show the chat bubble, you'll use a rounded rectangle view that you'll set as the background of the text view.&lt;/p&gt;

&lt;p&gt;To start, add another computed property to &lt;code&gt;ChatMessageRow&lt;/code&gt;, right above &lt;code&gt;text&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;chatBubble&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;RoundedRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember the shape views I mentioned earlier in the course? Another one of those is &lt;code&gt;RoundedRectangle&lt;/code&gt;, perfect for this use case: A chat bubble.&lt;/p&gt;

&lt;p&gt;You'll set this chat bubble as the background of the text. Inside &lt;code&gt;text&lt;/code&gt;, call the &lt;code&gt;background&lt;/code&gt; method with the chat bubble:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatBubble&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In SwiftUI, backgrounds can be infinitely complex. In this case, you're setting it to a rounded rect. You can also set it to colors, image views, other shape views or &lt;em&gt;any other SwiftUI view&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjchjcyh1xjy05s8n17ic.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjchjcyh1xjy05s8n17ic.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The text now has a background, but to make it a true speech bubble it needs a tail from the user's avatar to the message, like in comic books.&lt;/p&gt;

&lt;p&gt;To add this, you'll create a triangular view that you'll place between the avatar and the message in the stack. Add a new function to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;chatBubbleTriange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function receives a width and a height for the chat bubble tail, as well as whether the message is incoming or not. You'll use this information to construct the bubble and return it from the function.&lt;/p&gt;

&lt;p&gt;Next, add the following code to the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Path&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closeSubpath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You use a &lt;code&gt;Path&lt;/code&gt; view to construct the triangle. &lt;code&gt;Path&lt;/code&gt; is a special type of view that lets you create any arbitrary shape that you can think of.&lt;/p&gt;

&lt;p&gt;If this sounds complex, don't worry. &lt;code&gt;Path&lt;/code&gt; has a bunch of helper methods to construct shapes like straight lines, arcs, curves, rectangles, ellipses and more. By combining those simpler shapes, you can end up with shapes that would make Kandinsky jealous.&lt;/p&gt;

&lt;p&gt;When constructing a path, think of it like drawing with an imagined pen. You move the pen to its start position by calling &lt;code&gt;move(to:)&lt;/code&gt;. Once it's in position, you can press it down and draw by calling one of the &lt;code&gt;addX&lt;/code&gt; methods, where &lt;code&gt;X&lt;/code&gt; can be anything from line, arc, curve and other shapes.&lt;/p&gt;

&lt;p&gt;In this case, you first move the path to the center-left position of the view. You then draw a line to the top-right corner and then draw a line to the bottom-right corner. Finally, you call &lt;code&gt;closeSubpath&lt;/code&gt; which closes the path by drawing a line back to the start position.&lt;/p&gt;

&lt;p&gt;Now that you have the tail, add it to &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;chatBubbleTriange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;text&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgydbj0vgsjbf2p9l5a18.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgydbj0vgsjbf2p9l5a18.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The shape is good, but the view needs some tweaks. We need to trick the user into thinking the tail is a part of the message bubble. Add the following method calls to the bottom of &lt;code&gt;chatBubbleTriangle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clipped&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You modify the tail's z-index so that it's above the chat message. You then clip the view so that there's no shadow at the right edge. Finally, you adjust the padding so that it's overlapping with the chat message by one point.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwnei63git5s7rvrojyf8.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwnei63git5s7rvrojyf8.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it looks like a real speech bubble! This makes you one step closer to a real app since no chat app would be complete without speech bubbles. Let's tweak them a little bit more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding color to the speech bubbles
&lt;/h3&gt;

&lt;p&gt;Next, you'll color outgoing messages blue, and incoming messages white. Start by changing the text color in the &lt;code&gt;text&lt;/code&gt; computed variable, so that it's visible on both backgrounds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;body&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatBubble&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a similar modification to the chat bubble, except you can color it blue if the message is outgoing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;chatBubble&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;RoundedRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;white&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cometChatBlue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you need to match the tail's color to the bubble. In &lt;code&gt;chatBubbleTriangle&lt;/code&gt;, replace the first method call to &lt;code&gt;fill&lt;/code&gt; with the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;white&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cometChatBlue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preview now shows a blue message when it's not incoming. Nice!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykrbft0ev99zburil4py.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykrbft0ev99zburil4py.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaining messages
&lt;/h3&gt;

&lt;p&gt;As we discussed earlier, if the same user sends a couple of messages, you'll only show the avatar at the last message. For other messages, you'll show a spacer of the same width as the avatar in its place.&lt;/p&gt;

&lt;p&gt;Modify &lt;code&gt;body&lt;/code&gt; to add this change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isLastFromContact&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;chatBubbleTriange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;61&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the message is last from this contact, you show the avatar and the tail. Otherwise, you show a blank space. Earlier you learned that spacers take up as much space as they can. By modifying the spacer's frame, you make sure it has a fixed width.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fag56j2j4tpbmfg2d8cp0.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fag56j2j4tpbmfg2d8cp0.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, only the last message in a chain shows the avatar. We're almost there!&lt;/p&gt;

&lt;h3&gt;
  
  
  Reversing a horizontal stack in SwiftUI
&lt;/h3&gt;

&lt;p&gt;One final thing you need to tweak is to align outgoing messages to the right. To do this, you'll need to reverse the order of items in the &lt;code&gt;HStack&lt;/code&gt;, as well as flip the chat bubble's tail.&lt;/p&gt;

&lt;p&gt;You'll start by flipping the tail. Since you built it as a path, you can reverse the x coordinates of the path to mirror the triangle.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;chatBubbleTriangle&lt;/code&gt;, reverse the x-axis of the path if the message is outgoing by replacing the &lt;code&gt;Path&lt;/code&gt; initializer with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Path&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closeSubpath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll also need to reverse the padding by replacing the last three lines of the function with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your tail is sufficiently flipped.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd4vg3vdv5ejbac7tewui.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd4vg3vdv5ejbac7tewui.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you'll move on to the stack view by reversing the order of the items in the stack.&lt;/p&gt;

&lt;p&gt;Right now, there's no easy way to do this in SwiftUI. The way to do this is to add an &lt;code&gt;if&lt;/code&gt; check inside the stack, and repeat the views in the reverse order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isIncoming&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isLastFromContact&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;chatBubbleTriange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;61&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isLastFromContact&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;chatBubbleTriange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;61&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not the cleanest solution, but it's the best we can do right now.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnozdrjz3jbbey4y25q6l.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnozdrjz3jbbey4y25q6l.png" alt="Making a chat bubble in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your messages are now aligned to the right if they're coming from the current user. This concludes creating the message row. You can now take a small break by creating the text field. Or, take a small break, and &lt;em&gt;then&lt;/em&gt; create the text field. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the chat text field
&lt;/h2&gt;

&lt;p&gt;A chat screen is two things: The messages and a text field. In this section, you'll make a nice looking text field to let the user type in their messages.&lt;/p&gt;

&lt;p&gt;Before we get started, you'll need to download another image. Download the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat/raw/master/CometChat/CometChat/Assets.xcassets/send_message.imageset/send_message.png" rel="noopener noreferrer"&gt;send icon from here&lt;/a&gt;. Once downloaded, drag and drop the image inside you &lt;strong&gt;Assets.xcassets&lt;/strong&gt; file and name it &lt;strong&gt;send_message&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Start creating the text field by creating a new SwiftUI &lt;code&gt;View&lt;/code&gt; file called &lt;strong&gt;ChatTextField.swift&lt;/strong&gt;. Add two properties and a method to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ChatTextField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;sendAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt;

  &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;messageText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;sendButtonTapped&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;sendAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messageText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;messageText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The text field will receive a callback to call when the send button gets tapped. It will track the entered text inside a state variable, and pass the text via the callback back to the main chat screen.&lt;/p&gt;

&lt;p&gt;Next, modify the preview so that it shows the text field with a bit of spacing on the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kt"&gt;ChatTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sendAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can start working on the view. Inside &lt;code&gt;body&lt;/code&gt;, add a horizontal stack that contains a text field and a button to send the message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Type something"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$messageText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sendButtonTapped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"send_message"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You fix the text field's size to 60 points. In the button, you show the send icon and make sure its size is 25 by 25 points. Finally, you add a bit of padding to the whole stack and give it a white background.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F92m7a1qwcvdsh9txivl2.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F92m7a1qwcvdsh9txivl2.png" alt="Creating a chat text field in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should do one final modification by adding a shadow to the top of the view. Because you want the shadow only on top, you'll add a new thin rectangular view to the top, and apply a shadow to that rectangle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To add the rectangle, you first wrap the whole view inside of a vertical stack. You add the rectangle to the top of the stack and apply a shadow to the rectangle. You'll also set the &lt;code&gt;VStack&lt;/code&gt;'s frame to be 60 points high.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuarloz89t9mlw8ew30eu.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuarloz89t9mlw8ew30eu.png" alt="Creating a chat text field in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking good! You now have a text field and a view for each message. It's time to assemble them!&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it all together in a chat view
&lt;/h2&gt;

&lt;p&gt;Now, it's time to cash in all of your hard work so far, and put together the pieces to form a great looking chat view.&lt;/p&gt;

&lt;p&gt;Create a new SwiftUI view file named &lt;strong&gt;ChatView.swift&lt;/strong&gt;. Add the following properties to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ChatView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The chat view will receive two users: One that's currently logged in, and one that the user will chat with.&lt;/p&gt;

&lt;p&gt;You'll need to modify the previews to pass values for these two properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;ChatView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Other"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"other"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, scroll back to the &lt;code&gt;ChatView&lt;/code&gt; struct and add the following state property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Morbi scelerisque luctus velit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pellentesque ipsum. Mauris elem enes tumen mauris vitae tortor. Pellentesque ipsum. "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Phasellus enim erat esi, vestibulum veles?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Lorem ipsum dolor sit amet, consectetuer adipiscing elit."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="kt"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Mauris tincidunt sem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the messages you'll show on the screen. Right now, you're hard-coding them in the struct. Later, you'll be listening to a WebSocket channel and adding messages to this array as they come in — but that's in a later part of this course.&lt;/p&gt;

&lt;p&gt;Now you can add a list of messages to the view. Add a &lt;code&gt;body&lt;/code&gt; to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="kt"&gt;ChatMessageRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;isLastFromContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you learned earlier in the course, you combine a &lt;code&gt;ForEach&lt;/code&gt; with a &lt;code&gt;List&lt;/code&gt; to create a list of &lt;code&gt;ChatMessageRow&lt;/code&gt;s. You know the message is incoming if the message's sender is different from the current user.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk7tkvxcrsanzqh0s0maq.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk7tkvxcrsanzqh0s0maq.png" alt="Removing separators from a SwiftUI List"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks like you're having issues with the table view's separators. You've already learned a trick to deal with these: Using &lt;code&gt;UIAppearance&lt;/code&gt;. Add an initializer to the top of the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currentUser&lt;/span&gt;
  &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;receiver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;

  &lt;span class="kt"&gt;UITableView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tableFooterView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kt"&gt;UITableView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;separatorStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;
  &lt;span class="kt"&gt;UITableView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;
  &lt;span class="kt"&gt;UITableViewCell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the initializer, you use the global appearance proxies for the table view to remove the separators. You also remove all background colors from both the table view and the cells. This lets you change the background color in SwiftUI.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2bt63jh89bwvvp3ld2jj.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2bt63jh89bwvvp3ld2jj.png" alt="Removing separators from a SwiftUI List"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that the chat message looks different for chained messages? You'll have to add a way to determine if each message was the lest message sent by a user or just another message in the chain. Add the following method to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;isMessageLastFromContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You fetch the message at that index, as well as the next message. If the next message has a different sender, the current message is the last in the chain.&lt;/p&gt;

&lt;p&gt;Next, pass the result of this function to each chat message row. You'll also use this function to modify the spacing between the rows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="kt"&gt;ChatMessageRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nv"&gt;isIncoming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isLastFromContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isMessageLastFromContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRowInsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EdgeInsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isMessageLastFromContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the message is the last in a chain, you'll add a larger spacing to the bottom. You'll also add a bigger top spacing to the first row in the list so that it doesn't bump into the navigation bar.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxa969xig0h45fyfj1sw9.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxa969xig0h45fyfj1sw9.png" alt="Making a SwiftUI chat screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The list is looking great now! Let's move on to adding the text field you created earlier to the view.&lt;/p&gt;

&lt;p&gt;Start by creating a new function that will get called when the text field's send button is tapped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;onSendTapped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// TODO: Send message&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, wrap &lt;code&gt;body&lt;/code&gt; in a &lt;code&gt;VStack&lt;/code&gt; and add the text field to the bottom of the stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;ChatTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sendAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;onSendTapped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When wrapping views inside a stack, Xcode gives you several tricks you can use. If you &lt;strong&gt;Command-Click&lt;/strong&gt; the view, you can select &lt;strong&gt;Embed in VStack&lt;/strong&gt; to wrap a &lt;code&gt;VStack&lt;/code&gt; around that view. If you decide to do it manually, by selecting a piece of text and hitting &lt;strong&gt;Control-i&lt;/strong&gt; Xcode will reindent the text for you. Pretty nifty!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgb3uzvc2u7n63ldci1l1.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgb3uzvc2u7n63ldci1l1.png" alt="Making a SwiftUI chat screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since you made a reusable text field, this one line of code is all you need to add the text field to the view. Good job, you!&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing the background of a SwiftUI List
&lt;/h3&gt;

&lt;p&gt;Finally, you'll add a background to the screen. Previously, you used the &lt;code&gt;background&lt;/code&gt; method to color a view. Another way to do this is to use a &lt;code&gt;ZStack&lt;/code&gt;. After all, a &lt;code&gt;ZStack&lt;/code&gt; stacks views one on top of the other. If the top view has a clear background, the bottom view will show through and act as a background.&lt;/p&gt;

&lt;p&gt;Add the whole &lt;code&gt;body&lt;/code&gt; to a &lt;code&gt;ZStack&lt;/code&gt;, where you show the background color at the bottom of the stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;ZStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;edgesIgnoringSafeArea&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;ChatTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sendAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;onSendTapped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In SwiftUI, &lt;code&gt;Color&lt;/code&gt; is not only a struct that represents a color. It can also be used as a standalone view by itself! You use this fact to add a background color to the &lt;code&gt;ZStack&lt;/code&gt;. Because you set the table view's and the cells' background color to &lt;code&gt;.clear&lt;/code&gt;, the background shows through them.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff0v3rzatohdzv9hhikzb.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff0v3rzatohdzv9hhikzb.png" alt="Making a SwiftUI chat screen"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Our chat app is starting to take shape! We now have a way to log in, pick a person to chat with and, finally, a way to chat with them. At least, in theory.&lt;/p&gt;

&lt;p&gt;The remainder of this course will deal with less visual aspects of your app. The next section will deal with propagating state and data through your app and sharing data between SwiftUI views. Once you master that, you'll move on to networking and hooking your app up to the Internet.&lt;/p&gt;

&lt;p&gt;So, unless you want to keep chatting with dummy users forever, keep reading! :)&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
    </item>
    <item>
      <title>Creating a list in SwiftUI</title>
      <dc:creator>marinbenc🐧</dc:creator>
      <pubDate>Tue, 11 Feb 2020 07:52:26 +0000</pubDate>
      <link>https://dev.to/cometchat/swiftui-course-part-4-creating-a-list-in-swiftui-f28</link>
      <guid>https://dev.to/cometchat/swiftui-course-part-4-creating-a-list-in-swiftui-f28</guid>
      <description>&lt;p&gt;By this part of the course, you've already built a couple of different SwiftUI screens using a bunch of SwiftUI views. You've used &lt;code&gt;Text&lt;/code&gt;s, &lt;code&gt;Image&lt;/code&gt;s, &lt;code&gt;Rectangle&lt;/code&gt;s, &lt;code&gt;VStack&lt;/code&gt;s and &lt;code&gt;HStack&lt;/code&gt;s, but there's one type of screen we haven't yet built: A list.&lt;/p&gt;

&lt;p&gt;Lists (AKA table views) are at the core of almost all iOS apps. The most popular apps like Instagram, Twitter or Reddit all show a big list of stuff on their main screen. In this part of this SwiftUI course, you'll learn how to show a list of items in SwiftUI.&lt;/p&gt;

&lt;p&gt;You'll learn this by building a contacts screen. This screen will show all of the users your current user can chat with. By the end of this part, you'll have a screen that looks like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feetwlcs83ec25g8zxpd3.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feetwlcs83ec25g8zxpd3.png" alt="Showing a List in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before you can build that screen, though, you first need a way to navigate to it. Let's get started!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can always find the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat" rel="noopener noreferrer"&gt;finished project code on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Navigating to the contacts screen
&lt;/h2&gt;

&lt;p&gt;You'll start by creating a new SwiftUI view file for your contacts screen and naming it &lt;strong&gt;ContactsView.swift&lt;/strong&gt;. Change the struct to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContactsView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Contacts"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far it doesn't show much — you'll take care of that later. For now, let's add a way to navigate to this view. Open &lt;strong&gt;LoginView.swift&lt;/strong&gt; and change the navigation link's destination to show the newly created contacts view, instead of &lt;code&gt;EmptyView&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;NavigationLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ContactsView&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$showContacts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;EmptyView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run the app now and click the login button, you'll navigate to the view. Now we can fill it up with contacts! Well... in a bit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am creating this course in collaboration with CometChat, a modern chat platform to help you add chat to you Swift app. During the next few weeks, we’ll be releasing installments of our free SwiftUI course here on dev.to! In the course, you’ll dive deep into SwiftUI by building a real-world production-scale chat app, learning SwiftUI in a practical way, on a scale larger than a simple example app. Follow me to get notified of future parts of this course! You can also follow &lt;a href="https://twitter.com/cometchat" rel="noopener noreferrer"&gt;@CometChat&lt;/a&gt; on Twitter see the course of &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com" rel="noopener noreferrer"&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%2Favpunu4hqp1ut7enf5tq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in a List?
&lt;/h2&gt;

&lt;p&gt;First, we'll lay some groundwork on SwiftUI lists. In SwiftUI, Lists are created by using a view called, shockingly, &lt;code&gt;List&lt;/code&gt;. Much like &lt;code&gt;Group&lt;/code&gt; or &lt;code&gt;VStack&lt;/code&gt;, a &lt;code&gt;List&lt;/code&gt; is a sort of wrapper around a bunch of child views. It hugs all of its children in a tight embrace and positions them on the screen, one below the other, with separators, paddings, a scroll view and everything else you'd expect from a list.&lt;/p&gt;

&lt;p&gt;SwiftUI's &lt;code&gt;List&lt;/code&gt; is backed by a &lt;code&gt;UITableView&lt;/code&gt; on iOS, which means that the same cell reuse behavior you're used to is there on SwiftUI, too. Apple is an environmentally conscious company, after all, so cells are &lt;strong&gt;recycled&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of loading all of your rows at once, SwiftUI will only take up memory for the rows that are currently visible. As you scroll, the rows that disappear are not destroyed, but instead, go into a pool of deactivated rows. When the list needs a new row, instead of allocating one, it will take one from the pool.&lt;/p&gt;

&lt;p&gt;When the list takes a row from the pool, it will apply any necessary changes to its views (text values, images, etc.) to match the item at the current index. This gives the appearance of having many rows, while in reality only a couple are ever loaded at once.&lt;/p&gt;

&lt;p&gt;All this is to say that &lt;code&gt;List&lt;/code&gt;s are very fast and memory-efficient, regardless of how many rows there are in the list.&lt;/p&gt;

&lt;p&gt;In UIKit, you'd probably first create a table view and then think about placing items in that table. The component-based nature of SwiftUI means you'll have to reverse your thinking: Start from smaller views and work your way up.&lt;/p&gt;

&lt;p&gt;That's why you'll first create the view for each row in your list and only then begin assembling the contacts screen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: On websites like StackOverflow, you'll often see people suggesting you replace &lt;code&gt;List&lt;/code&gt; with a &lt;code&gt;ScrollView&lt;/code&gt; and a &lt;code&gt;ForEach&lt;/code&gt; view to achieve a desired look. In some cases, this works well. However, &lt;code&gt;ScrollView&lt;/code&gt; will load all the items at once. If you have a lot of items, a plain scroll view will be &lt;em&gt;much less efficient&lt;/em&gt; than a &lt;code&gt;List&lt;/code&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Making a SiwftUI List row view
&lt;/h2&gt;

&lt;p&gt;Before we create our items, we need a model struct to house information about each contact. Create a new plain Swift file called &lt;strong&gt;Contact.swift&lt;/strong&gt;. Change the contents to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Identifiable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll notice &lt;code&gt;Contact&lt;/code&gt; conforms to &lt;code&gt;Identifiable&lt;/code&gt;. To easily show an array of items in a list, those items need to each have a unique identifier. Remember, rows are reused, so the list needs a way of uniquely identifying each item. You conform to &lt;code&gt;Identifiable&lt;/code&gt; by giving the struct an &lt;code&gt;id&lt;/code&gt; property that is unique.&lt;/p&gt;

&lt;p&gt;To create the row view, create a new SwiftUI &lt;code&gt;View&lt;/code&gt; file and name it &lt;strong&gt;ContactRow.swift&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This is what you'll end up with:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5bdylaf1crggx98vfker.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5bdylaf1crggx98vfker.png" alt="Creating a list cell / row view in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This view has a few things going on. It shows the avatar with a little online badge, the contact's name, as well as their last message. &lt;/p&gt;

&lt;p&gt;As you just learned, it's better to start from smaller views and build up to larger views. That's why you'll start by creating a separate view for the avatar and the online badge.&lt;/p&gt;

&lt;p&gt;First, you'll need to add a few placeholder avatars to your app. Download the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat/raw/master/CometChat/CometChat/Assets.xcassets/avatar_placeholder0.imageset/profile0.png" rel="noopener noreferrer"&gt;avatar placeholder image&lt;/a&gt; and add it to &lt;strong&gt;Assets.xcassets&lt;/strong&gt;. Name the image &lt;code&gt;avatar_placeholder0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With that in place, add the view struct to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 2&lt;/span&gt;
    &lt;span class="kt"&gt;ZStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// 3&lt;/span&gt;
      &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"avatar_placeholder0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// 4&lt;/span&gt;
      &lt;span class="kt"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this code, you create a new SwiftUI view for the avatar. You'll use &lt;code&gt;AvatarView&lt;/code&gt; inside the view for the list's row. Here's what's going on in the struct:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The view has two properties, one for the avatar URL and one that tells it whether that contact is online. For now, you'll use placeholder avatars. Later in the course, you'll learn how to fetch them from the internet.&lt;/li&gt;
&lt;li&gt;Inside of &lt;code&gt;body&lt;/code&gt;, you'll position the image and the online indicator in a &lt;code&gt;ZStack&lt;/code&gt;. You've already learned about &lt;code&gt;VStack&lt;/code&gt; and &lt;code&gt;HStack&lt;/code&gt;. &lt;code&gt;ZStack&lt;/code&gt; is similar to those, but in 3D! Instead of arranging items below or to the right of each other, it arranges items &lt;em&gt;on top&lt;/em&gt; of each other. This is useful for when you want two views to overlap. In this example, you want the online indicator to be on top of the image.&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;ZStack&lt;/code&gt;, you first create an image view with the placeholder and give it a fixed size of 37 by 37 points.&lt;/li&gt;
&lt;li&gt;Next, you create a circular view of 10 by 10 points and color it green or gray depending on if the user is online or not. You also position the circle to be in the bottom-right corner of the image.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll need to modify the preview to see the view you just created. Scroll down to the &lt;code&gt;PreviewProvider&lt;/code&gt; struct and change its content to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;AvatarView_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows the avatar view in all its glory, with a fixed size, inside a group.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe9e7oe4pybzy1yqjynhj.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe9e7oe4pybzy1yqjynhj.png" alt="Creating a circular avatar view in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll use the group later to show your contact row as well. Speaking of which, let's get on creating that view.&lt;/p&gt;

&lt;p&gt;Add another &lt;code&gt;View&lt;/code&gt; struct to the same file, underneath &lt;code&gt;AvatarView&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContactItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Identifiable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ContactItem&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the view that will be shown in the list. Instead of adding a bunch of properties to the struct, you create a nested struct to house all of the data necessary for displaying a contact.&lt;/p&gt;

&lt;p&gt;Again, you use &lt;code&gt;Identifiable&lt;/code&gt; to help the list reuse items. In this case, passing along the contact's ID will suffice.&lt;/p&gt;

&lt;p&gt;For this to be a complete view, you'll also need to add &lt;code&gt;body&lt;/code&gt; to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unread&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
    &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;236&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;240&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;254&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To center the contents of the view, you'll place the image and the texts inside a vertical stack. For now, the stack contains only a spacer. You also give the stack a light blue background color if the last message is unread, set its width to stretch out as far as it can and make sure its height is a fixed 67 points.&lt;/p&gt;

&lt;p&gt;Next, modify the preview so it shows the contact view underneath the avatar view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ContactItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Some Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Last message is a pretty big message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ContactItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Other Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Last message is a pretty big message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test all the variations of the contact view, you'll show one preview where the user is online and the message is unread, and one where the user if offline and the message was already read.&lt;/p&gt;

&lt;p&gt;All of this code to display a completely empty view! Let's fix that. &lt;/p&gt;

&lt;p&gt;Add the avatar view inside a horizontal stack to &lt;code&gt;ContactRow&lt;/code&gt;'s &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You place the avatar in a horizontal stack so that you can add the two text views to the right of the avatar. You also add another spacer to the bottom of the &lt;code&gt;VStack&lt;/code&gt; so that everything is vertically centered in the row.&lt;/p&gt;

&lt;p&gt;Next, add the two texts to the view between the avatar view and the spacer in the &lt;code&gt;HStack&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;AvatarView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// New code:&lt;/span&gt;
    &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unread&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;medium&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;regular&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unread&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;medium&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;regular&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// ---&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Place the two texts inside a vertical stack since they're arranged one on top of the other. You'll also limit the number of lines of text to 1, to make sure the text doesn't wrap. Finally, you'll add some padding around the vertical stack so that there's a space between the texts and the image.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwfqa8krot3y7mqmia8kb.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwfqa8krot3y7mqmia8kb.png" alt="Creating a list cell / row view in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's your contact item! It displays the name, the avatar, the last message as well as if the contact is online or not, all at a glance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using SwiftUI Lists
&lt;/h2&gt;

&lt;p&gt;Now, it's time to head over to &lt;strong&gt;ContactsView.swift&lt;/strong&gt; to add a bunch of contacts inside a list.&lt;/p&gt;

&lt;p&gt;You'll start by creating a state property that will hold your contacts. For now, fill it up with a couple of fake contacts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ContactItem&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Some Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"This is my last message that I sent you"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Other Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"This is my last message that I sent you"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Third Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;lastMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"This is my last message that I sent you"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;unread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this array to populate a list. Replace &lt;code&gt;body&lt;/code&gt; with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use a &lt;code&gt;List&lt;/code&gt; with an array, you can pass the array to the list, as well as a function that will create the view for each row, given the array element for that row. Since you already created your row view, you can just create that view with the contact.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Remember that to show a dynamic array of items in a &lt;code&gt;List&lt;/code&gt;, those items need to conform to the &lt;code&gt;Identifiable&lt;/code&gt; protocol as described above.&lt;/p&gt;
&lt;/blockquote&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fur9ibgm9jvsirxupdesh.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fur9ibgm9jvsirxupdesh.png" alt="Showing a list of custom views in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In only three lines of code, you have a list of dynamic items from an array. Take &lt;em&gt;that&lt;/em&gt;, UIKit!&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing separators from a SwiftUI List
&lt;/h2&gt;

&lt;p&gt;However, there is a slight problem with this screen. Instead of a nice-looking list, we have a space and a separator between each item. This happens because SwiftUI uses a plain &lt;code&gt;UITableView&lt;/code&gt; to show the list, which has built-in separators and insets.&lt;/p&gt;

&lt;p&gt;To change this, you first need to tweak the way you created the list. I showed you a shortcut for creating a list from an array, but there's another way to do it using &lt;code&gt;ForEach&lt;/code&gt;. Change &lt;code&gt;body&lt;/code&gt; to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;List&lt;/code&gt; receives a builder that builds an &lt;em&gt;array&lt;/em&gt; of views. You'll build this array using &lt;code&gt;ForEach&lt;/code&gt;. &lt;code&gt;ForEach&lt;/code&gt; is a special type of view that replaces itself with a list of views, one below the other. In the above code,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...is exactly the same as writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of these three views will get treated as a separate row by the list. Again, because a &lt;code&gt;List&lt;/code&gt; needs to identify items, you'll pass the current index (&lt;code&gt;self&lt;/code&gt;) as the ID of that item.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In UIKit it was somewhat difficult to combine different types of cells. It was especially hard to combine static and dynamic cells. In SwiftUI, since &lt;code&gt;List&lt;/code&gt; receives an array of rows, it's very easy to combine static and dynamic content. You can first return a hard-coded row, then a &lt;code&gt;ForEach&lt;/code&gt; of a couple of different dynamic rows, then another static one, and so on. A &lt;code&gt;List&lt;/code&gt; can hold any combination of static and dynamic rows of different types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that you changed the way you build your list, you can apply a little hack to remove the separators. &lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;List&lt;/code&gt; is backed by a &lt;code&gt;UITableView&lt;/code&gt;, any global changes you make to table views will also apply to SwiftUI lists. UIKit provides an API to make global changes to all instances of a view called &lt;code&gt;UIAppearance&lt;/code&gt;. Each &lt;code&gt;UIView&lt;/code&gt; subclass has an &lt;code&gt;appearance&lt;/code&gt; method that returns something called an &lt;strong&gt;appearance proxy&lt;/strong&gt;. Changing properties of the appearance proxy propagates those changes to all instances of the class, like changing a static property.&lt;/p&gt;

&lt;p&gt;You can change the table view's appearance proxy to remove the separators, thus removing all separators from you &lt;code&gt;List&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add the following initializer to the view struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;UITableView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tableFooterView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kt"&gt;UITableView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;separatorStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Appearance proxies are not limited to table views. Lots of other SwiftUI views are backed by UIKit views. You can also use this pattern to change the look of navigation bars, toggles, texts and other views.&lt;/p&gt;

&lt;p&gt;Keep in mind though, this is a bit of a hack. For now, SwiftUI is backed by UIKit, but this is an implementation detail that you don't want to rely on. Nothing is stopping Apple from ditching &lt;code&gt;UITableView&lt;/code&gt; and making their own thing in SwiftUI. I'm showing you this trick because, currently, there's no better way to remove separators.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the struct loads, it will remove all separators from every table view in the app.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdl7fiut33jfilu3m5pug.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdl7fiut33jfilu3m5pug.png" alt="How to remove separators from a SwiftUI List"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The list now looks much cleaner, but I think it looks better &lt;em&gt;with&lt;/em&gt; separators. &lt;/p&gt;

&lt;h2&gt;
  
  
  Adding custom separators to a SwiftUI List
&lt;/h2&gt;

&lt;p&gt;You might be pulling your hair out by now because you just removed them! Well, SwiftUI is flexible enough that, instead of using &lt;code&gt;UITableView&lt;/code&gt;'s separators, it's better to make our own using plain SwiftUI views.&lt;/p&gt;

&lt;p&gt;Go back the view for your item: &lt;strong&gt;ContactRow.swift&lt;/strong&gt;. Inside &lt;code&gt;body&lt;/code&gt;, use a rectangle view at the bottom of the &lt;code&gt;VStack&lt;/code&gt; to add separators back in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="c1"&gt;// New code:&lt;/span&gt;
      &lt;span class="kt"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rectangle will stretch the width of the view by default, all you need to change is to set the height to 1 point and set the color to whichever separator color you'd like.&lt;/p&gt;

&lt;p&gt;Head back to &lt;strong&gt;ContactView.swift&lt;/strong&gt; to see your list:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh0tebda0o5k2s1cmlydi.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh0tebda0o5k2s1cmlydi.png" alt="Adding a custom List separator in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's already looking great, but there's one small issue I can see. There's still extra space around each item.&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing space around SwiftUI List rows
&lt;/h2&gt;

&lt;p&gt;SwiftUI adds space around each row in a &lt;code&gt;List&lt;/code&gt; by default. This space is called the &lt;em&gt;inset&lt;/em&gt; of a list row. The inset is an instance of &lt;code&gt;EdgeInsets&lt;/code&gt;, a struct that holds values for how much the view is shifted from the leading, trailing, top and bottom edges.&lt;/p&gt;

&lt;p&gt;You can remove the inset by calling &lt;code&gt;listRowInsets&lt;/code&gt; on the view inside the list, and giving it a value of &lt;code&gt;EdgeInsets()&lt;/code&gt;, where all the values are zero.&lt;/p&gt;

&lt;p&gt;Add the following to &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRowInsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EdgeInsets&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, &lt;em&gt;now&lt;/em&gt; it's looking perfect.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftkkajuqfpqpvjfbydkxk.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftkkajuqfpqpvjfbydkxk.png" alt="Removing the default spacing around SwiftUI List rows"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Except... I'd still like to add one final touch. In the original design, there was a shadow underneath the last item, giving the whole screen a sense of depth that is currently missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a shadow to a SwiftUI view
&lt;/h2&gt;

&lt;p&gt;To add a shadow to the row you'll call, you guessed it: &lt;code&gt;shadow&lt;/code&gt;. This method takes the color of the shadow, its radius, as well as an x and y value that determines how much the shadow is offset from the view.&lt;/p&gt;

&lt;p&gt;SwiftUI adds shadows to &lt;em&gt;opaque&lt;/em&gt; parts of the view. That is parts that have some sort of color. Right now, the background of your rows is &lt;em&gt;transparent&lt;/em&gt;. It appears white because the color underneath them is white. To show the shadow underneath a row, you need to first color the background in white, and &lt;em&gt;then&lt;/em&gt; add the shadow.&lt;/p&gt;

&lt;p&gt;Add the following to &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="kt"&gt;ContactRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRowInsets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;EdgeInsets&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
            &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withAlphaComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; 
            &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You set the background color to white and apply a shadow to the view. You only want to add a shadow to the last row, though, so you make the shadow completely transparent if the row is not the last.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F809ew79guu9qv6spkcyc.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F809ew79guu9qv6spkcyc.png" alt="Adding a shadow to a SwiftUI view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, &lt;em&gt;now&lt;/em&gt; I'm happy with the look of this screen. Let's run this in the simulator so see it in action.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F52z0u05zud92lkwjx9mq.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F52z0u05zud92lkwjx9mq.png" alt="Creating a SwiftUI List view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh boy, it looks like you're not off the hook yet! There's one more issue to take care of. The original design shows a title in the navigation bar, which isn't there in our version. Thankfully, that's easy to add.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a navigation bar title in SwiftUI
&lt;/h2&gt;

&lt;p&gt;To add a navigation bar title, you need to call &lt;code&gt;navigationBarTitle&lt;/code&gt; on the &lt;em&gt;root view&lt;/em&gt; of your &lt;code&gt;body&lt;/code&gt;. In your case, that's the list view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigationBarTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Contacts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;displayMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, SwiftUI adds a large, bold navigation bar title with lots of space around it. You already saw this when you were building your login screen. In this case, you want a more subtle title that is part of the navigation bar. That's why you pass &lt;code&gt;.inline&lt;/code&gt; as the display mode, integrating the title with the bar.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feetwlcs83ec25g8zxpd3.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feetwlcs83ec25g8zxpd3.png" alt="Adding a regular navigation bar to a SwiftUI view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now&lt;/em&gt; it looks perfect. No, for real this time. You can take a break and pat yourself on the back, I won't be bothering you with design changes anymore.&lt;/p&gt;

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

&lt;p&gt;You're slowly moving more and more towards a fully-fledged SwiftUI chat app! You built out a contacts screen that shows a list of users.&lt;/p&gt;

&lt;p&gt;If you want to know more about SwiftUI lists, here are a few links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In UIKit, table views can hold sections of items. The same is true for SwiftUI &lt;code&gt;List&lt;/code&gt;s. To organize rows into sections, place a &lt;a href="https://developer.apple.com/documentation/swiftui/section" rel="noopener noreferrer"&gt;&lt;code&gt;Section&lt;/code&gt; view&lt;/a&gt; inside a list, and rows inside the section.&lt;/li&gt;
&lt;li&gt;There's a couple of different list styles that you can use off the shelf. There's a default list, a plain list, a grouped one (used in the Settings app in iOS), a carousel and one that looks like the lists in an iOS sidebar. You can find all of them &lt;a href="https://developer.apple.com/documentation/swiftui/liststyle" rel="noopener noreferrer"&gt;here&lt;/a&gt;. To change the style of your list, call &lt;a href="https://developer.apple.com/documentation/swiftui/list/3364399-liststyle" rel="noopener noreferrer"&gt;&lt;code&gt;listStyle&lt;/code&gt;&lt;/a&gt; on the list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the contacts in your list might be hard-coded for now, everything is in place to load these users from the internet — in later parts of this SwiftUI course. So keep reading!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
    </item>
    <item>
      <title>Creating a login screen in SwiftUI</title>
      <dc:creator>marinbenc🐧</dc:creator>
      <pubDate>Tue, 11 Feb 2020 07:52:06 +0000</pubDate>
      <link>https://dev.to/cometchat/swiftui-course-part-3-creating-a-login-screen-in-swiftui-380c</link>
      <guid>https://dev.to/cometchat/swiftui-course-part-3-creating-a-login-screen-in-swiftui-380c</guid>
      <description>&lt;p&gt;In the last part of this SwiftUI course, you've learned all about how to create and arrange SwiftUI views to craft beautiful interfaces. In this part, you'll put those skills to test by building out a login screen for your app.&lt;/p&gt;

&lt;p&gt;You'll build a login screen with an email field, some information and a button at the bottom. Besides just building the screen, we'll also add a way to navigate from the welcome screen you created in the last part to the new login screen.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F11183jdsil8je1e8l6j3.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F11183jdsil8je1e8l6j3.png" alt="Creating a login screen in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ready to get started?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat" rel="noopener noreferrer"&gt;finished project code on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Kicking things off
&lt;/h2&gt;

&lt;p&gt;To create the login screen, create a new SwiftUI View file called &lt;strong&gt;LoginView.swift&lt;/strong&gt;. For now, change the body to display a text saying "Log In":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;LoginView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll fill up this placeholder screen later, but you'll first need a way to navigate to the screen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am creating this course in collaboration with CometChat, a modern chat platform to help you add chat to you Swift app. During the next few weeks, we’ll be releasing installments of our free SwiftUI course here on dev.to! In the course, you’ll dive deep into SwiftUI by building a real-world production-scale chat app, learning SwiftUI in a practical way, on a scale larger than a simple example app. Follow me to get notified of future parts of this course! You can also follow &lt;a href="https://twitter.com/cometchat" rel="noopener noreferrer"&gt;@CometChat&lt;/a&gt; on Twitter see the course of &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com" rel="noopener noreferrer"&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%2Favpunu4hqp1ut7enf5tq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigation in SwiftUI
&lt;/h2&gt;

&lt;p&gt;Two SwiftUI views will help you with navigation: &lt;code&gt;NavigationView&lt;/code&gt; and  &lt;code&gt;NavigationLink&lt;/code&gt;. &lt;code&gt;NavigationView&lt;/code&gt; is SwiftUI's version of &lt;code&gt;UINavigationController&lt;/code&gt;: It manages a stack of views and shows a navigation bar on top of them. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;NavigationLink&lt;/code&gt; is similar to a &lt;code&gt;Button&lt;/code&gt;, but it triggers presenting a new view in the navigation stack when it's pressed. To work correctly, a &lt;code&gt;NavigationLink&lt;/code&gt; needs to be nested inside a &lt;code&gt;NavigationView&lt;/code&gt;. In UIKit terms, if &lt;code&gt;NavigationView&lt;/code&gt; is the navigation controller, &lt;code&gt;NavigationLink&lt;/code&gt; is a segue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a SwiftUI Navigation View and a navigation bar
&lt;/h3&gt;

&lt;p&gt;In iOS apps, you'd often have one navigation controller that will be the initial view controller of your app. You can achieve a similar effect in SwiftUI by making the initial view a &lt;code&gt;NavigationView&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The initial view is determined by the &lt;code&gt;SceneDelegate&lt;/code&gt;. If you look inside &lt;strong&gt;SceneDelegate.swift&lt;/strong&gt; you'll find an implementation of &lt;code&gt;scene(_:willConnectTo:, options:)&lt;/code&gt; that creates a content view and adds it to the window.&lt;/p&gt;

&lt;p&gt;Instead of creating a plain &lt;code&gt;WelcomeView&lt;/code&gt;, change &lt;code&gt;contentView&lt;/code&gt; so that you wrap the welcome screen in a navigation view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;contentView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NavigationView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;WelcomeView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;contentView&lt;/code&gt;, just like any other SwiftUI view, can be arbitrarily complex. The scene delegate is a good place to add global configuration, like changing colors, adding routing, subscribing to global events and other changes that affect the whole app.&lt;/p&gt;

&lt;p&gt;Run the project now and you'll notice a giant space on the top of your welcome screen.&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%2Fwmrcrapreylduvltenuv.png" 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%2Fwmrcrapreylduvltenuv.png" alt="SwiftUI fixing Navigation default padding"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This space is taken up by an empty navigation bar. Let's look at how to change the look and content of this bar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling the navigation bar in SwiftUI
&lt;/h3&gt;

&lt;p&gt;Let's fill up the navigation bar with a title on the welcome screen. Open &lt;strong&gt;WelcomeView.swift&lt;/strong&gt;, and add a navigation bar title to the top-most &lt;code&gt;VStack&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigationBarTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run the project, you might notice there's now &lt;em&gt;two&lt;/em&gt; texts saying "Create an account". &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%2Fgklq8furyp21nvblllaa.png" 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%2Fgklq8furyp21nvblllaa.png" alt="Adding a navigation bar title in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remove the one inside the &lt;code&gt;VStack&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/* Remove from here...
    Text("Create an account")
      .modifier(BodyText())
      .padding()
    ... to here*/&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The view looks the same as it did before, but the text is now part of the navigation bar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you're wondering how to get the default-looking iOS navigation bar, you can use &lt;code&gt;navigationBarTitle(_:displayMode:)&lt;/code&gt; and pass in &lt;code&gt;.inline&lt;/code&gt; as the display mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since your view is wrapped inside a &lt;code&gt;NavigationView&lt;/code&gt;, you can now use &lt;code&gt;NavigationLink&lt;/code&gt; to present the login screen. Wrap the primary button in &lt;code&gt;body&lt;/code&gt; inside a &lt;code&gt;NavigationLink&lt;/code&gt; (instead of a &lt;code&gt;Button&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Change this line:&lt;/span&gt;
      &lt;span class="kt"&gt;NavigationLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;LoginView&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;SecondaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Sign Up"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like &lt;code&gt;Button&lt;/code&gt;, &lt;code&gt;NavigationLink&lt;/code&gt; will wrap around a view and make it interactable. Instead of calling a function, though, the navigation link will present the provided view when it's tapped.&lt;/p&gt;

&lt;p&gt;If you run the project now and tap the log in button, you'll be taken to your login view.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy744bb3lgha0ir0spmxx.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy744bb3lgha0ir0spmxx.gif" alt="Presenting a new view from a button in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The view inside the navigation link can be anything you want, but be aware that views that respond to touches, like buttons, will &lt;em&gt;consume&lt;/em&gt; the touch and it won't propagate to the navigation link. In other words, buttons inside navigation links won't trigger the presentation. Watch out for those hungry buttons, lest they eat your touches!&lt;/p&gt;

&lt;h2&gt;
  
  
  Making a reusable SwiftUI text field
&lt;/h2&gt;

&lt;p&gt;Now that you can navigate to the login view, you'll start building out that view. &lt;/p&gt;

&lt;p&gt;Since you're building a login form, you'll first build a reusable text field that you can use throughout your app. Small reusable views are a leitmotif of SwiftUI apps! Once you're done, it will look like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn4clu40uffa2vqhvklmk.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn4clu40uffa2vqhvklmk.png" alt="Making a text field in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Already you can see the views you'll combine to create this text field. In a vertical stack, you'll need &lt;code&gt;Text&lt;/code&gt; for the title, a &lt;code&gt;TextField&lt;/code&gt; to edit the text, an &lt;code&gt;Image&lt;/code&gt; to show the icon and a way to display the line on the bottom of the view.&lt;/p&gt;

&lt;p&gt;Before you start working on the view, let's first add the little email icon. You can find the image &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat/raw/master/CometChat/CometChat/Assets.xcassets/email.imageset/email.png" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Drag it over to your &lt;strong&gt;Assets.xcassets&lt;/strong&gt; file and name it &lt;strong&gt;email&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a new SwiftUI View file called &lt;strong&gt;ErrorTextField.swift&lt;/strong&gt;. It's called error text field because you'll add the ability to show an error if the text is invalid. Change the struct to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Binding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIKeyboardType&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;

  &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Binding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIKeyboardType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIKeyboardType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;@escaping&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;placeholder&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iconName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iconName&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keyboardType&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks like a lot of code but don't worry — it's a boilerplate initializer that sets up all the necessary properties of the view. You'll need a title and a placeholder, the image name of the icon, a function to validate the text and the keyboard type of the text field.&lt;/p&gt;

&lt;p&gt;You'll also need a &lt;strong&gt;binding&lt;/strong&gt; to the text. A binding is similar to a state variable, but it's used to bind data between two different views. For instance, you can provide the text field with a binding to your text. The text field will change the text, and your view will be re-drawn. &lt;/p&gt;

&lt;p&gt;Think of binding as a state variable that you can pass to other views. It's kind of like giving someone your phone number and telling them to call you when something changes.&lt;/p&gt;

&lt;p&gt;In this case, you'll receive a binding to the text that you'll pass along to the &lt;code&gt;TextField&lt;/code&gt; view.&lt;/p&gt;

&lt;p&gt;Since this view can show an error, add a computed property that will determine whether an error should be shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;showsError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wrappedValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isEmpty&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wrappedValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no point in showing the error if the text is empty. If the text is &lt;em&gt;not&lt;/em&gt; empty, you'll use the provided text validation function to determine if an error should get shown.&lt;/p&gt;

&lt;p&gt;Next, create the &lt;code&gt;body&lt;/code&gt; for this view by adding the title to a stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lightGray&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make your life easier, you'll also modify the preview to show the different possible states of the text field all at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ErrorTextField_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"test@email.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

      &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"test@email.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"some@email.com"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

      &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"test@email.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someemail.com"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nv"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You'll notice the text is &lt;code&gt;.constant("some value")&lt;/code&gt;. The &lt;code&gt;constant&lt;/code&gt; is a factory static function that creates a binding that never changes. It's useful for testing and previews, like in the above example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just like in the previous part of this SwiftUI course, you create multiple previews by adding views into a &lt;code&gt;Group&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnd01c4o8kibtmzqvgqhn.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnd01c4o8kibtmzqvgqhn.png" alt="Previewing multiple states of a SwiftUI view at once."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you can see what you're doing, let's add the text field and the email icon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Laying out SwiftUI views horizontally
&lt;/h3&gt;

&lt;p&gt;With that out of the way, you can continue building the view by adding the text field and the icon. To make sure the text field and the icon are next to each other, you can use an &lt;code&gt;HStack&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lightGray&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// New code:&lt;/span&gt;
    &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autocapitalization&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contentMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're already familiar with &lt;code&gt;VStack&lt;/code&gt;. Well, &lt;code&gt;HStack&lt;/code&gt; works the same, except horizontally. You arrange a text field and an image in a horizontal stack.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F18e2umevewe4ra4xvg1x.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F18e2umevewe4ra4xvg1x.png" alt="Creating a horizontal stack with HStack in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;TextField&lt;/code&gt; is the SwiftUI equivalent of UIKit's &lt;code&gt;UITextField&lt;/code&gt;, except it's plain by default — which is exactly what we need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you want to style a text field to look like a regular UIKit text field, you can call &lt;code&gt;textFieldStyle(RoundedBorderTextFieldStyle())&lt;/code&gt; on the text field. The rounded border style is the one used by the good old &lt;code&gt;UITextField&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the previous part of this SwiftUI course, you learned about making image views expand to match their parent. In this case, you want the image to have a fixed size. That's why you call &lt;code&gt;frame&lt;/code&gt; and pass it an exact width and height.&lt;/p&gt;

&lt;h3&gt;
  
  
  Displaying basic shape views in SwiftUI
&lt;/h3&gt;

&lt;p&gt;Finally, you'll add the border on the bottom of the text field. Since the border is just a plain rectangular view with no content, you can use a &lt;code&gt;Rectangle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lightGray&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;HStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// New code:&lt;/span&gt;
    &lt;span class="kt"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;showsError&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; 
        &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;189&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;215&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As its name suggests, &lt;code&gt;Rectangle&lt;/code&gt; is just, well, a rectangle. Perfect for displaying borders or backgrounds. You set its height to 2 and leave other dimensions up to SwiftUI. You'll also set its color to red if &lt;code&gt;showsError&lt;/code&gt; is true, otherwise, you'll use a light gray color.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyflmxkahw82k8a32ojel.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyflmxkahw82k8a32ojel.png" alt="Using SwiftUI Rectangle to create a border for a view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Rectangle&lt;/code&gt; is only one of a few basic shape views. There's also &lt;code&gt;RoundedRectangle&lt;/code&gt;, &lt;code&gt;Circle&lt;/code&gt;, &lt;code&gt;Capsule&lt;/code&gt; and &lt;code&gt;Ellipse&lt;/code&gt;. Remember these when you need to draw shapes — there's no need to resort to &lt;code&gt;CAShapeLayer&lt;/code&gt; anymore.&lt;/p&gt;

&lt;p&gt;You now have a nice looking text field that is flexible enough to be used throughout your app. It's time to put it to action in the login screen!&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a SwiftUI login screen
&lt;/h2&gt;

&lt;p&gt;Now, finally, you can get to work on the login screen! Head back to &lt;strong&gt;LoginView.swift&lt;/strong&gt; and change &lt;code&gt;body&lt;/code&gt; to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, you'll make sure stack view items are aligned to the left edge, just like in the last part of this SwiftUI course. Add a spacing of 26 points between each item and make sure the "Log In" text is styled as a title. You'll also add the system padding to the stack.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjkdbcn0a6r901wwqu63f.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjkdbcn0a6r901wwqu63f.png" alt="Creating a login screen in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that the text field you built receives a validation function? Let's create one that will validate an email. Add the following method to the struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;.[A-Za-z]{2,64}"&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;predicate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NSPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"SELF MATCHES %@"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;predicate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method checks the email string against a regular expression. If the email doesn't contain an @ sign, a dot, and text around both of those, this function will return &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, add a state variable for the entered text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With those two pieces in place, you can now add a text field for the email to your view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c1"&gt;// New code:&lt;/span&gt;
    &lt;span class="kt"&gt;ErrorTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"mail@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;iconName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;keyboardType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emailAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nv"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of the properties should be self-explanatory, except maybe this weird &lt;code&gt;$text&lt;/code&gt; thing. Don't worry, you're not programming PHP! &lt;code&gt;$&lt;/code&gt; is a special character that converts an &lt;code&gt;@State&lt;/code&gt; variable to a binding. Remember, bindings are state variables that can be changed from a different view. In this case, &lt;code&gt;LoginView&lt;/code&gt; will pass the &lt;code&gt;email&lt;/code&gt; as a binding to &lt;code&gt;ErrorTextField&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcn8cfc533wval68bit7i.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcn8cfc533wval68bit7i.png" alt="Creating a login screen in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, create an empty function that you'll call when the user presses the login button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Initiate network request&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, add a spacer and a button that calls this function. As you learned in the previous part of this SwiftUI course, the spacer will expand to make sure everything above it is on top, while the button is on the very bottom of the stack. Add the following to &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever the button is pressed, SwiftUI will call your &lt;code&gt;login&lt;/code&gt; function which, currently, does absolutely nothing.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F11183jdsil8je1e8l6j3.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F11183jdsil8je1e8l6j3.png" alt="Creating a login screen in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't be disappointed, you'll fix this soon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Presenting a SwiftUI view asynchronously
&lt;/h3&gt;

&lt;p&gt;Later in this course, &lt;code&gt;login&lt;/code&gt; will perform a network request to log the user in and then present a contacts screen. For now, though, you'll navigate to an empty screen when the button is pressed.&lt;/p&gt;

&lt;p&gt;Earlier, you learned how to use &lt;code&gt;NavigationLink&lt;/code&gt; to present a new view in the navigation stack when a button is pressed. Often, though, you don't want to &lt;em&gt;immidiately&lt;/em&gt; go to a new screen. You'll usually want to perform a check, a network request or some other bit of logic, and then present a new screen programmatically when you're done. SwiftUI has a way to do that, but it is a bit clumsy.&lt;/p&gt;

&lt;p&gt;First, create a new state variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;showContacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll navigate to the contacts screen when this variable gets set to &lt;code&gt;true&lt;/code&gt;. To do this, you can use a &lt;code&gt;NavigationLink&lt;/code&gt;, but differently from before. Instead of wrapping a button in the navigation link, you'll show a hidden link that the user won't see. &lt;/p&gt;

&lt;p&gt;You'll also use a different &lt;code&gt;NavigationLink&lt;/code&gt; initializer: &lt;code&gt;NavigationLink(destination:isActive:label)&lt;/code&gt;. The key here is &lt;code&gt;isActive&lt;/code&gt;: This is a binding to a bool variable. When it gets set from &lt;code&gt;false&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; &lt;code&gt;NavigationLink&lt;/code&gt; will know to trigger the presentation.&lt;/p&gt;

&lt;p&gt;Add the navigation link to the bottom of &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;NavigationLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;EmptyView&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$showContacts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;EmptyView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By making navigation link's body an &lt;code&gt;EmptyView&lt;/code&gt; you make sure that the user can't see the link. You set its &lt;code&gt;isActive&lt;/code&gt; binding to the state variable you created earlier.&lt;/p&gt;

&lt;p&gt;Finally, set &lt;code&gt;showContacts&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; at the bottom of &lt;code&gt;login&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;showContacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user presses the login button, SwiftUI calls &lt;code&gt;login&lt;/code&gt;, which sets &lt;code&gt;showContacts&lt;/code&gt; to true, triggering the &lt;code&gt;NavigationLink&lt;/code&gt;, which then presents an empty view in the navigation stack. This Rube Goldberg machine of events is what happens when you try to do an imperative thing, like presenting a view programmatically, in a declarative UI framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Presenting multiple SwiftUI views asynchronously
&lt;/h3&gt;

&lt;p&gt;To expand this &lt;code&gt;NavigationLink&lt;/code&gt; pattern to multiple views, you'd have to have one state variable for each view you want to present, leading to multiple flags in your view that can be false and true at the same time. This doesn't scale well.&lt;/p&gt;

&lt;p&gt;To solve this problem, &lt;code&gt;NavigationLink&lt;/code&gt; offers a &lt;em&gt;third&lt;/em&gt; initializer: &lt;code&gt;NavigationLink(_:destination:tag:selection:)&lt;/code&gt;. While the one you used previously has a binding to a Boolean, this initializer is generic. &lt;code&gt;selection&lt;/code&gt; is a binding to any &lt;code&gt;Hashable&lt;/code&gt; type, like integers, strings and even enums. If the current value of &lt;code&gt;selection&lt;/code&gt; matches the value of &lt;code&gt;tag&lt;/code&gt;, the link will get triggered.&lt;/p&gt;

&lt;p&gt;For instance, let's say you wanted to present either a login or a registration screen based on some logic. You'd start by defining an enum with cases for each of the views you'd like to present.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="kt"&gt;PresentedView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;registration&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll also need a state variable to track which view should be shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;viewToPresent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PresentedView&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, inside &lt;code&gt;body&lt;/code&gt;, you can create hidden navigation links to each of your views.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;NavigationLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;LoginView&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; 
  &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$viewToPresent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;EmptyView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;NavigationLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;RegistrationView&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; 
  &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$viewToPresent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;EmptyView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you want to present one of these two views, set &lt;code&gt;viewToPresent&lt;/code&gt; to the corresponding value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;viewToPresent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The navigation link will check the bound value, and if it matches its tag, present the view. This solution is easier to scale, so if you have more than one view you'd like to present, I suggest you use this approach.&lt;/p&gt;

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

&lt;p&gt;And there you have it! You've built out a login screen and by doing so you've learned a bunch of important SwiftUI concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to present and style SwiftUI text fields, as well as how to use basic SwiftUI shape views.&lt;/li&gt;
&lt;li&gt;How to use a &lt;code&gt;NavigationView&lt;/code&gt; to show and style a navigation bar.&lt;/li&gt;
&lt;li&gt;How to push a view when you press a button using &lt;code&gt;NavigationLink&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;How to push SwiftUI views programmatically using &lt;code&gt;NavigationLink(destination:isActive)&lt;/code&gt; or &lt;code&gt;NavigationLink(destination:tag:selection:)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd say that's a good day's work! No need to stop now, though.&lt;/p&gt;

&lt;p&gt;In the next part, you'll learn all about SwiftUI lists by building out a contacts screen to show your user's friends. You'll also begin your journey into making network requests!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
    </item>
    <item>
      <title>Your first SwiftUI screen</title>
      <dc:creator>marinbenc🐧</dc:creator>
      <pubDate>Tue, 11 Feb 2020 07:51:44 +0000</pubDate>
      <link>https://dev.to/cometchat/swiftui-course-part-2-your-first-swiftui-screen-cdo</link>
      <guid>https://dev.to/cometchat/swiftui-course-part-2-your-first-swiftui-screen-cdo</guid>
      <description>&lt;p&gt;SwiftUI is a unifying framework in more ways than one. Whether you're building an Apple Watch, Apple TV, iPhone, iPad or even Mac apps, SwiftUI will let you do that. Whether you're a designer, web developer or simply someone interested in building apps, SwiftUI is still for you. It might take a bit longer than for seasoned iOS veterans, but you'll get the hang of things!&lt;/p&gt;

&lt;p&gt;Once you're on the other side of this course, you won't just be an iOS developer  &lt;strong&gt;you'll be a SwiftUI developer&lt;/strong&gt;. Capable of building for all Apple platforms!&lt;/p&gt;

&lt;p&gt;This course will guide you through building a real-world chat application. You'll build each part of the app including logging the user in, displaying their contacts and chatting over the internet. By building a real app, you'll quickly learn practical SwiftUI skills that you can use in the real world.&lt;/p&gt;

&lt;p&gt;In this first part, you'll make a welcome screen for the app. You'll learn about existing SwiftUI views, how to make your own views, how to lay them out and space them as well as how to style them to your liking.&lt;/p&gt;

&lt;p&gt;On your way to victory, SwiftUI might try to sabotage you at some point with its opaque error messages or hard-to-find APIs. Remember, fortune favors the brave, so let's dive in with courage!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find the finished project of this part of the SwiftUI course &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Making SwiftUI Views
&lt;/h2&gt;

&lt;p&gt;We'll start our SwiftUI adventure by building out a welcome screen for our app. It will be a static screen with some information, an image and buttons to either log in or sign up to our chat service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thepracticaldev.s3.amazonaws.com/i/izoybo8y7r0zl1j2ylco.png" rel="noopener noreferrer"&gt;Your first SwiftUI screen!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A SwiftUI app is a huge tree of &lt;code&gt;View&lt;/code&gt;s. &lt;code&gt;View&lt;/code&gt; is a SwiftUI protocol that represents any view that can be shown on the screen, whether it's a huge detail screen or a simple label.&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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1572001105818_Screenshot%2B2019-10-25%2Bat%2B12.52.28.png" 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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1572001105818_Screenshot%2B2019-10-25%2Bat%2B12.52.28.png" alt="SwiftUI View hierarchy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's start by creating a new SwiftUI app. Open up &lt;strong&gt;Xcode&lt;/strong&gt;. For this to work, you'll need Xcode 11 or later.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am creating this course in collaboration with CometChat, a modern chat platform to help you add chat to you Swift app. During the next few weeks, we’ll be releasing installments of our free SwiftUI course here on dev.to! In the course, you’ll dive deep into SwiftUI by building a real-world production-scale chat app, learning SwiftUI in a practical way, on a scale larger than a simple example app. Follow me to get notified of future parts of this course! You can also follow &lt;a href="https://twitter.com/cometchat" rel="noopener noreferrer"&gt;@CometChat&lt;/a&gt; on Twitter see the course of &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com" rel="noopener noreferrer"&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%2Favpunu4hqp1ut7enf5tq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the Xcode welcome screen, click &lt;strong&gt;Create a new Xcode project&lt;/strong&gt;. Select the &lt;strong&gt;Single View App&lt;/strong&gt; template under &lt;strong&gt;iOS&lt;/strong&gt; and hit &lt;strong&gt;Next&lt;/strong&gt;. Name the app anything you'd like. I named my app "CometChat". Make sure &lt;strong&gt;SwiftUI&lt;/strong&gt; is selected as the &lt;strong&gt;User Interface&lt;/strong&gt; and click &lt;strong&gt;Next&lt;/strong&gt; again. Select a good location to save the project and click &lt;strong&gt;Create&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%2F644wvha36zyq2dfpeeoo.png" 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%2F644wvha36zyq2dfpeeoo.png" alt="Creating a new SwiftUI app in Xcode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats! You just made your first SwiftUI app. This is the end of this course. &lt;em&gt;Just kidding&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Next, you'll create a new SwiftUI view. Click &lt;strong&gt;File &amp;gt; New &amp;gt; File...&lt;/strong&gt; and, as the template, select &lt;strong&gt;SwiftUI View&lt;/strong&gt; and name it &lt;strong&gt;WelcomeView&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You'll get presented with an almost empty struct, except for one computed property called &lt;code&gt;body&lt;/code&gt;. &lt;strong&gt;This is the most important part of a view.&lt;/strong&gt; &lt;code&gt;body&lt;/code&gt; returns the contents of your view. iOS will periodically call this computed property to re-draw what's on the screen.&lt;/p&gt;

&lt;p&gt;You might have noticed &lt;code&gt;body&lt;/code&gt;'s type is &lt;code&gt;some View&lt;/code&gt;. &lt;code&gt;View&lt;/code&gt; is a protocol, and the &lt;code&gt;some&lt;/code&gt; keyword tells Swift that &lt;code&gt;body&lt;/code&gt; can be any concrete type, as long as it conforms to &lt;code&gt;View&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Change the contents of the struct to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;WelcomeView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the right of your code, you'll see the &lt;strong&gt;Canvas&lt;/strong&gt;. This is where you can preview the views you're making. If the preview updating is paused, click the &lt;strong&gt;Resume&lt;/strong&gt; button in the top-right corner.&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%2F4v5y21tjf3je028o588q.png" 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%2F4v5y21tjf3je028o588q.png" alt="Your first SwiftUI view!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you make changes to your code, the Canvas will update to show your changes. At least in theory. Often the canvas will be too quick to update and try to compile partially-written code or run into some other issue. You'll get used to clicking &lt;strong&gt;Try Again&lt;/strong&gt; and &lt;strong&gt;Resume&lt;/strong&gt; a lot. :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Arranging SwiftUI views with stacks
&lt;/h3&gt;

&lt;p&gt;Let's add another label to the view, below the one you just added. You might be tempted to simply add another &lt;code&gt;Text&lt;/code&gt; below the current one, but if you do that you'd get a compiler error. The error happens because &lt;code&gt;body&lt;/code&gt; is a single &lt;code&gt;View&lt;/code&gt;: You can't return two values. Instead, you need a view that would wrap &lt;em&gt;around&lt;/em&gt; the two texts, like a SwiftUI birthday present.&lt;/p&gt;

&lt;p&gt;SwiftUI has a couple of different views that group other views and the one you'll use the most is &lt;code&gt;VStack&lt;/code&gt; and &lt;code&gt;HStack&lt;/code&gt;. These are the SwiftUI equivalents to UIKit's UIStackView, stacking for &lt;strong&gt;v&lt;/strong&gt;ertical and &lt;strong&gt;h&lt;/strong&gt;orizontal stack views, respectively. If you're coming from web development, &lt;code&gt;VStack&lt;/code&gt; and &lt;code&gt;HStack&lt;/code&gt; are the Flexbox of SwiftUI.&lt;/p&gt;

&lt;p&gt;These two views are your &lt;strong&gt;primary layout tool&lt;/strong&gt; in SwiftUI. By arranging items into stacks, nesting stacks within stacks and controlling stack alignment and item spacing you can make almost any layout imaginable.&lt;/p&gt;

&lt;p&gt;Let's change &lt;code&gt;body&lt;/code&gt; so that it returns a vertical stack of two text views:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see the two labels centered in the middle of the preview screen. &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%2Fi1wn4adl9d7acj725o7q.png" 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%2Fi1wn4adl9d7acj725o7q.png" alt="A SwiftUI VStack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look at the screen we're trying to make, though, the two texts need to be aligned to the left and sit on top of the view. You can align items in a stack by passing the alignment in the stack's initializer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the texts are aligned to the left, but they're still not on the top of the screen. &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%2F54jhb1c8ajs3mzao16jp.png" 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%2F54jhb1c8ajs3mzao16jp.png" alt="Left-align items in a SwiftUI VStack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's look at how we can fix that.&lt;/p&gt;

&lt;h4&gt;
  
  
  Vertically aligning VStack items with spacers
&lt;/h4&gt;

&lt;p&gt;The stack's &lt;code&gt;alignment&lt;/code&gt; controls the alignment of the items along the &lt;em&gt;opposite axis of the stack&lt;/em&gt;, so for &lt;code&gt;VStack&lt;/code&gt;, it controls the horizontal alignment. To align items along the &lt;em&gt;major axis&lt;/em&gt; you can either manually space the items or use a special view called &lt;code&gt;Spacer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;Spacer&lt;/code&gt;, as its name suggests, is an empty view that stretches out to fill out as much space as it can. When you place it inside a &lt;code&gt;VStack&lt;/code&gt;, it will stretch &lt;em&gt;horizontally&lt;/em&gt;. If you place it in an &lt;code&gt;HStack&lt;/code&gt;, it stretches &lt;em&gt;vertically&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Add a spacer to the bottom of your stack to see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;VStack&lt;/code&gt; is the birthday present, the spacers are the birthday party balloons, filling up the horizontal space as long as they can, pushing the two text views to the top of the screen.&lt;/p&gt;

&lt;p&gt;To get the feel for how spacers behave, experiment by placing spacers at different positions inside the stack. Here are a couple of examples:&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%2Fy4ajo4ate7855obyxtcd.png" 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%2Fy4ajo4ate7855obyxtcd.png" alt="SwiftUI VStack and Spacer cheat sheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, by placing spacers at different positions you can align and space out your items anywhere in the stack. To fine-tune the spacing, you'll use &lt;em&gt;padding&lt;/em&gt; — but you'll read more on that later in this part of the SwiftUI course.&lt;/p&gt;

&lt;p&gt;For now, we'll take a break from laying out our view and venture into styling the text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling SwiftUI views with &lt;code&gt;View&lt;/code&gt; methods
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;View&lt;/code&gt;s have all kinds of methods to tweak their properties, whether its changing their size, colors, state, opacity or anything else that can be changed. Some of these methods are common to all views, like methods for changing the frame or padding. Others are specific to that view, such as the font of a &lt;code&gt;Text&lt;/code&gt; or the enabled state of a &lt;code&gt;Button&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;According to the screenshot of the view we're building, the second text in our stack needs to have a big and bold font. To make this change, call the &lt;code&gt;font&lt;/code&gt; method on the text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;largeTitle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're used to UIKit, you're probably familiar with classes like &lt;code&gt;UIFont&lt;/code&gt; or &lt;code&gt;UIColor&lt;/code&gt;. SwiftUI has its equivalents, but drops the &lt;code&gt;UI&lt;/code&gt; prefix and makes them a struct. &lt;/p&gt;

&lt;p&gt;There's also one big difference between the UIKit and SwiftUI versions: &lt;strong&gt;SwiftUI's fonts and colors are &lt;em&gt;late binding&lt;/em&gt;.&lt;/strong&gt; This means that a &lt;code&gt;Font&lt;/code&gt; is just a &lt;em&gt;token&lt;/em&gt; or an identifier for some font. This token only gets resolved to a specific font during runtime, depending on the environment it's running in. For instance, &lt;code&gt;Font.largeTitle&lt;/code&gt; gets resolved to San Francisco on iOS, but could be Helvetica &lt;a href="https://github.com/SwiftWebUI/SwiftWebUI" rel="noopener noreferrer"&gt;on the web&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;SwiftUI modifier methods are &lt;em&gt;non-mutating&lt;/em&gt;. Instead, they return a new &lt;code&gt;View&lt;/code&gt; with the changes applied. This has two consequences. First, you can chain modifier calls one after the other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// returns a new Image&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contentMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns a new View&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns a new View&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondly, because each of these methods creates a new view, the order of calling the methods can sometimes be important. A modifier called later can override what you set earlier, like in CSS or when subclassing a Swift class.&lt;/p&gt;

&lt;p&gt;If you're the kind of developer who prefers a GUI over plain code, you can &lt;strong&gt;Control-Option-Click&lt;/strong&gt; a SwiftUI view (either in the code or the preview) and open the &lt;strong&gt;SwiftUI Inspector&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%2Fjkv56ua2hmxgbz1djqs9.png" 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%2Fjkv56ua2hmxgbz1djqs9.png" alt="SwiftUI Inspector in Xcode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This opens up a popup window that will let you tweak the settings of a view. As you make changes, SwiftUI will generate code for those changes and add them to your &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing the color of a SwiftUI Text
&lt;/h3&gt;

&lt;p&gt;While we're beautifying our views, why not add some color. As you can guess by now, adding color is a simple matter of calling a method on the label:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;largeTitle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like &lt;code&gt;Font&lt;/code&gt;, &lt;code&gt;Color&lt;/code&gt; is also a late-binding token, which means that the actual color value of the color above will depend on the current environment, including what platform it's running on as well as whether it's running in light or dark mode.&lt;/p&gt;

&lt;p&gt;Even SwiftUI &lt;code&gt;Color&lt;/code&gt;s with specific names like &lt;code&gt;.blue&lt;/code&gt; will result in a different color in light and dark mode. These are called &lt;em&gt;adaptive colors&lt;/em&gt;, and you can make your own!&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding your own adaptive colors
&lt;/h3&gt;

&lt;p&gt;You'll add a new color for the text content of your app. Open &lt;strong&gt;Assets.xcassets&lt;/strong&gt; in the main folder of your app in Xcode. Right-click on the list of assets and select &lt;strong&gt;New Color Set&lt;/strong&gt;. At first, you'll see a white color with "Universal" below it. But, if you take a look at the &lt;strong&gt;Attributes Inspector&lt;/strong&gt;, you'll see there's a bunch of different environment combinations you can set.&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%2Fqt7xpt2zs9cdam5fqos1.png" 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%2Fqt7xpt2zs9cdam5fqos1.png" alt="Adding a SwiftUI adaptable color for dark mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, you can set one color for CarPlay in dark mode, a different color for Apple TVs in dark mode, and a third color for iPhones.&lt;/p&gt;

&lt;p&gt;For now, select only &lt;strong&gt;Universal&lt;/strong&gt; in the &lt;strong&gt;Devices&lt;/strong&gt; list, and &lt;strong&gt;Any, Dark&lt;/strong&gt; in the &lt;strong&gt;Appearances&lt;/strong&gt; dropdown. This allows you to set a different color for light and dark mode on all devices.&lt;/p&gt;

&lt;p&gt;Select the &lt;strong&gt;Any Appearance&lt;/strong&gt; color and in the &lt;strong&gt;Attributes Inspector&lt;/strong&gt; select &lt;strong&gt;8-bit Hexadecimal&lt;/strong&gt; for the &lt;strong&gt;Input Method&lt;/strong&gt; and enter the hex value #&lt;code&gt;2D313F&lt;/code&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%2Fz8eft8r7agwbgid5cblg.png" 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%2Fz8eft8r7agwbgid5cblg.png" alt="Adding a SwiftUI adaptable color for dark mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Dark Appearance plain white will suffice. Select the &lt;strong&gt;Color&lt;/strong&gt; in the sidebar and rename it to &lt;strong&gt;body&lt;/strong&gt;. This name is important because that's how we'll access it in code.&lt;/p&gt;

&lt;p&gt;Create a new plain Swift file called &lt;strong&gt;Colors.swift&lt;/strong&gt;. Replace the contents of the file with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;UIKit&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;cometChatBlue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;71&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;219&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;shadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;71&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;219&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;248&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;249&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;251&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;UIColor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;63&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds new static properties to &lt;code&gt;Color&lt;/code&gt; and &lt;code&gt;UIColor&lt;/code&gt;. We can use these colors throughout our app without having to copy and paste color names or specific values. Having everything in one place also means we can easily change these colors later.&lt;/p&gt;

&lt;p&gt;Now that you have the color you can use it to make your text prettier. Head back to &lt;strong&gt;WelcomeView.swift&lt;/strong&gt; and add a color to the first text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;largeTitle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cometChatBlue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F8beaz6oapubbe082t2y5.png" 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%2F8beaz6oapubbe082t2y5.png" alt="Adding a SwiftUI adaptable color for dark mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extending &lt;code&gt;Color&lt;/code&gt; with static properties is a great way to add reusability to our app. You can go a step further to make &lt;em&gt;any changes&lt;/em&gt; to a view reusable. Let's do that next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling SwiftUI views with view modifiers
&lt;/h3&gt;

&lt;p&gt;So far you have a title and a body text styled as they look in the screenshot above. You'll use the same text treatment (font and color combination) throughout your whole app. Instead of copying and pasting all the method calls in every &lt;code&gt;View&lt;/code&gt; with texts, it would be better to have a way to mark titles and body text in a more reusable way.&lt;/p&gt;

&lt;p&gt;SwiftUI lets you do that with &lt;strong&gt;View Modifiers&lt;/strong&gt;. Structs and classes in your app can implement the &lt;code&gt;ViewModifier&lt;/code&gt; protocol which has one required method that receives and returns a view. The idea is that you receive a view, perform any necessary transformations and return it back to the caller.&lt;/p&gt;

&lt;p&gt;You'll add two modifiers, one for the body text and one for titles. Create another plain Swift file and name it &lt;strong&gt;TextModifiers.swift&lt;/strong&gt;. Add a new view modifier to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ViewModifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Font&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;largeTitle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cometChatBlue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You implement the required method by receiving a view, applying a new font and foreground color and returning the changed view.&lt;/p&gt;

&lt;p&gt;Similarly, add another struct below the one you just created for the body text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ViewModifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the body text, you'll leave the font as it is and only change the color. Now, you can go back to &lt;strong&gt;WelcomeView.swift&lt;/strong&gt; and replace the styling you applied with the modifiers by calling the &lt;code&gt;modifier&lt;/code&gt; method on the text views:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now use these modifiers in any future views. When you want to change the look of your apps content, you can change the modifier the apply the changes everywhere in your app.&lt;/p&gt;

&lt;p&gt;Since view modifiers return a &lt;code&gt;View&lt;/code&gt;, you have the complete power of SwiftUI inside a modifier. This means you can even do complex changes like embed the view in a stack, scale it, adjust its spacing, add overlays and &lt;a href="https://sarunw.com/posts/swiftui-viewmodifier/" rel="noopener noreferrer"&gt;make whichever changes you can think of&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Spacing SwiftUI views with padding
&lt;/h3&gt;

&lt;p&gt;I think that's enough styling for now. It's time to get back to laying out our screen with &lt;strong&gt;padding&lt;/strong&gt;. SwiftUI doesn't have Auto Layout or constraints, but that doesn't mean you can't do everything you did in UIKit. It might be even easier. &lt;em&gt;At least sometimes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The method you use for this is called &lt;code&gt;padding&lt;/code&gt;, and it has two optional parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Edge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGFloat&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first parameter is the set of edges to apply the padding to, while the second is the actual value of the padding. By default, the first parameter applies the padding to all edges. If you omit the length, it will be &lt;code&gt;nil&lt;/code&gt; which will apply the &lt;strong&gt;default system padding&lt;/strong&gt; to the view.&lt;/p&gt;

&lt;p&gt;Usually, you'd want to apply the default padding. The advantage of the default padding is that it's automatically adjusted to the device you're using. Smaller devices will have a smaller padding and vice-versa.&lt;/p&gt;

&lt;p&gt;Change the &lt;code&gt;body&lt;/code&gt; of your view to add a padding to both of the texts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To the body text, you add a default padding to every edge by calling &lt;code&gt;padding()&lt;/code&gt;. The title text doesn't need a padding on top, so you add the system padding only to the bottom, leading (left) and trailing (right) edges.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://thepracticaldev.s3.amazonaws.com/i/xcn3k2juk4vbr4jqm41u.png" rel="noopener noreferrer"&gt;Adding padding to a SwiftUI view&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can combine the first and second parameter of &lt;code&gt;padding&lt;/code&gt; to achieve your desired effect. Here are some examples of different ways you can call &lt;code&gt;padding&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;padding()&lt;/code&gt; applies system padding to all edges.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding(.leading)&lt;/code&gt; applies the system padding to the left edge.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding([.bottom, .leading, .trailing])&lt;/code&gt; applies the system padding to three edges.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding(.top, 20)&lt;/code&gt; adds a padding of 20 points to the top edge.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding([.bottom, .top], 0)&lt;/code&gt; makes the top and bottom padding zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining stacks and padding you can intuitively make pixel-perfect layouts. At least, once you get used to it. :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Nesting SwiftUI stacks
&lt;/h3&gt;

&lt;p&gt;In UIKit, one of the most common view types are stack and table views. The same goes for SwiftUI: Your views will often be a big tree of nested stacks. In the screenshot of the screen you're making there's an image with a text below the two texts you just created. &lt;/p&gt;

&lt;p&gt;Both the image and the text are centered, so add another &lt;code&gt;VStack&lt;/code&gt; inside the existing one, that you'll center horizontally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"""
        This is a sample app.
        Create an account or login to begin chatting.
        """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multilineTextAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You add another &lt;code&gt;VStack&lt;/code&gt; that will hold the image and the text. The text also has the body text modifier. You make sure the text is centered and add a padding of 40 points on the leading and trailing edges, so it doesn't touch the edges of the screen.&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%2Fv02ozcx5aarm4wsncg13.png" 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%2Fv02ozcx5aarm4wsncg13.png" alt="SwiftUI Nested VStacks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Displaying images in SwiftUI
&lt;/h3&gt;

&lt;p&gt;Now that we added the text that's below the image, it's time to add the image. Image views in SwiftUI are called &lt;code&gt;Image&lt;/code&gt;, and they can be tricky to parse at first.&lt;/p&gt;

&lt;p&gt;Before you add an image view, you first need to add the image itself. You can find the &lt;a href="https://github.com/cometchat-pro-tutorials/swift-ui-chat/raw/master/CometChat/CometChat/Assets.xcassets/welcome.imageset/welcome.png" rel="noopener noreferrer"&gt;welcome image here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Open &lt;strong&gt;Assets.xcassets&lt;/strong&gt; and drag the image into the list of assets. Make sure the name is &lt;strong&gt;welcome&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, you can add a new &lt;code&gt;Image&lt;/code&gt; to the inner &lt;code&gt;VStack&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"""
    This is a sample app.
    Create an account or login to begin chatting.
    """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multilineTextAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You give the &lt;code&gt;Image&lt;/code&gt; the name of the asset you created. Give it a padding of 35 points at the bottom (between the image and the text), as well as a padding of 80 on the sides.&lt;/p&gt;

&lt;p&gt;The image looks good, but there's a &lt;em&gt;small&lt;/em&gt; issue: Our whole UI is now broken.&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%2Frp26y2k9ltwkem5z93sl.png" 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%2Frp26y2k9ltwkem5z93sl.png" alt="Making an Image resizable in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It would be ideal if the image scaled according to the device size and how much space it has to grow. On an iPhone SE, the image should be smaller than on an 11 Pro Max.&lt;/p&gt;

&lt;p&gt;We'll deal with this issue in a second, but let's first take a look at how we can spot issues like this in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Previewing SwiftUI views on a different device
&lt;/h3&gt;

&lt;p&gt;You can tweak the SwiftUI preview to see your views at different sizes. The preview screen isn't magic: It's loaded from a struct in the file that implements &lt;code&gt;PreviewProvider&lt;/code&gt;. The preview provider is similar to a &lt;code&gt;View&lt;/code&gt;. It has one computed property where you return what should be drawn inside the Canvas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;WelcomeView_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;WelcomeView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change this view in the same way you can change any other &lt;code&gt;View&lt;/code&gt;. There are also preview-specific methods that control the size and look of the previews.&lt;/p&gt;

&lt;p&gt;Call &lt;code&gt;previewDevice&lt;/code&gt; inside the &lt;code&gt;previews&lt;/code&gt; property and display an iPhone SE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;WelcomeView_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;WelcomeView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewDevice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;PreviewDevice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;rawValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"iPhone SE"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F2hma5xgpcn60364iod13.png" 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%2F2hma5xgpcn60364iod13.png" alt="Making an Image resizable in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now see that the image doesn't scale according to screen size. Let's fix that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling a SwiftUI Image
&lt;/h3&gt;

&lt;p&gt;To make an &lt;code&gt;Image&lt;/code&gt; view resizable you need to, you guessed it, call the &lt;code&gt;resizable&lt;/code&gt; method! Add the following two new lines to &lt;code&gt;body&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"welcome"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contentMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"""
    This is a sample app.
    Create an account or login to begin chatting.
    """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multilineTextAlignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default the image will just scale to fill its available space, which you probably don't want. Usually, you want to maintain the image's aspect ratio so that it doesn't look stretched out. &lt;/p&gt;

&lt;p&gt;To do that in SwiftUI, you can use the &lt;code&gt;aspectRatio&lt;/code&gt; method which receives a parameter telling it how to scale the image. &lt;code&gt;.fit&lt;/code&gt; scales the image so that it always fits inside its space, leading to letter-boxing. On the other hand, &lt;code&gt;.fill&lt;/code&gt; scales it so that it fills the whole space, but you won't see the whole image.&lt;/p&gt;

&lt;p&gt;In the above code, you first call &lt;code&gt;resizable&lt;/code&gt; on the image to tell SwiftUI that it can stretch out the image if needed. Then, you call &lt;code&gt;aspectRatio&lt;/code&gt; with &lt;code&gt;.fit&lt;/code&gt; to make sure the image always fits within the screen, 80 points from each edge.&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%2Fs4djrbnde22aqkrtqsiq.png" 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%2Fs4djrbnde22aqkrtqsiq.png" alt="Making an Image resizable in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you change the device back to &lt;code&gt;iPhone 11&lt;/code&gt; in the preview you'll notice the image now scales to fit its available size, no Auto Layout needed.&lt;/p&gt;

&lt;p&gt;We're almost done with our welcome screen! The final step is to add the two buttons on the bottom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating buttons in SwiftUI
&lt;/h2&gt;

&lt;p&gt;To build out a screen like this in UIKit, you'd use a view controller, and house all of your view related things in there. Usually, this is &lt;em&gt;not&lt;/em&gt; how you'll build SwiftUI views.&lt;/p&gt;

&lt;p&gt;SwiftUI does away with the distinction between view and view controller and it's built so that you compose tons of tiny views to build your screen.&lt;/p&gt;

&lt;p&gt;That's what you've been doing: &lt;code&gt;Text&lt;/code&gt;, &lt;code&gt;VStack&lt;/code&gt; and &lt;code&gt;Image&lt;/code&gt; are all small views that do one thing well, but by combining them you've created an already good-looking screen.&lt;/p&gt;

&lt;p&gt;Now it's time we make your own small SwiftUI views that you can use throughout the app. These views will be the two buttons you see on the bottom of the screen you're building.&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%2Fhvdxesp2d38yhseoxapm.png" 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%2Fhvdxesp2d38yhseoxapm.png" alt="Creating a Button in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new SwiftUI &lt;code&gt;View&lt;/code&gt; file called &lt;strong&gt;ButtonViews&lt;/strong&gt;, and change the struct to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uppercased&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to build a big blue button with rounded corners. You'll start with a good old text view.&lt;/p&gt;

&lt;p&gt;A button can hold &lt;em&gt;any other view&lt;/em&gt;, no matter how complex. With that in mind, our button is looking a little plain.&lt;/p&gt;

&lt;p&gt;At this point, you'll get an error because the automatically generated preview references the wrong view name. Change the preview to show your button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ButtonViews_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Primary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyz5neq14kmyyrsd9ujl9.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyz5neq14kmyyrsd9ujl9.png" alt="Creating a SwiftUI Button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll make it look better, but before we go on, let's do some preview setup to make our lives easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing the size of a SwiftUI preview
&lt;/h3&gt;

&lt;p&gt;Earlier in this section of the course, you learned how to preview your SwiftUI views on different devices. Most of your views will be reusable UI components, so it doesn't make sense to show a whole iPhone with a tiny view in the middle of a blank screen.&lt;/p&gt;

&lt;p&gt;Instead, you can preview them in a small window. Change the preview struct to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ButtonViews_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Primary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the preview shows a small rectangle that houses our button.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbojw21g5rsjh0ultmcey.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbojw21g5rsjh0ultmcey.png" alt="Changing the preview size in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice and neat! Let's get back to our buttons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling SwiftUI buttons
&lt;/h3&gt;

&lt;p&gt;Let's deal with that plain-looking button! Start by adding a background and a shadow to the button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uppercased&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, you now have a rounded blue blob, which is a start.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fymgp3gh0fhrmt23mbca9.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fymgp3gh0fhrmt23mbca9.png" alt="Making a Button in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, change the color and add some padding around the text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uppercased&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's one new method here: &lt;code&gt;frame&lt;/code&gt;. While padding determines how much space there is around the content, the frame determines how big the content is.&lt;/p&gt;

&lt;p&gt;You can either specify a constant size or you can make &lt;em&gt;suggestions&lt;/em&gt; to SwiftUI about how it should size the view. Here, you set the maximum width to infinite, making the view stretch to fit the size of its parent.&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%2Fnvegusjew8ksx7bxp6e1.png" 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%2Fnvegusjew8ksx7bxp6e1.png" alt="Making a Button in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our button is looking perfect! Let's add another, secondary button.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the secondary button
&lt;/h3&gt;

&lt;p&gt;To create the secondary button, you'll use a complex programming technique used by generations of programmers: copying and pasting. Because SwiftUI views are short pieces of code that are all in a single struct, you can easily copy and paste a view, modify it slightly and get a whole new look.&lt;/p&gt;

&lt;p&gt;For the secondary button, copy over the primary button and change the colors a bit to match the screenshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SecondaryButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uppercased&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks great... &lt;em&gt;I think&lt;/em&gt;. To see the button you need to change your preview first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Showing multiple SwiftUI previews
&lt;/h3&gt;

&lt;p&gt;You might be tempted to replace &lt;code&gt;Primary&lt;/code&gt; with &lt;code&gt;Secondary&lt;/code&gt; in the preview and call it a day. But, why show just one view, when you can show both of them at once?&lt;/p&gt;

&lt;p&gt;If you wrap the views inside a &lt;code&gt;Group&lt;/code&gt;, the Canvas will show each grouped view as a separate preview.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Primary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="kt"&gt;SecondaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Secondary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can see both of the buttons at once.&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%2F4agglx3amdlh5quvn1dk.png" 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%2F4agglx3amdlh5quvn1dk.png" alt="Previewing two SwiftUI views at once"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is especially useful when you have views that can show multiple states. For instance, we can show a preview for buttons that have long titles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;Group&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Primary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"This button has a really long title"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="kt"&gt;SecondaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Secondary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;previewLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F1meryrtk6jn4q21bvaog.png" 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%2F1meryrtk6jn4q21bvaog.png" alt="Showing multiple View states in a SwiftUI preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This makes it easy to see how your changes affect different states of your views, making sure you spot a lot of bugs without having to build and click around your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using custom SwitUI views
&lt;/h2&gt;

&lt;p&gt;With our buttons created, let's add them to the welcome screen. Back in &lt;strong&gt;WelcomeView.swift&lt;/strong&gt;, add a new &lt;code&gt;VStack&lt;/code&gt; with the two buttons, the final addition to the welcome screen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create an account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;BodyText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connect with people around the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TitleText&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// New code:&lt;/span&gt;
    &lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;SecondaryButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Sign Up"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trailing&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// ---&lt;/span&gt;

    &lt;span class="kt"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use your &lt;code&gt;View&lt;/code&gt;s just like any other SwiftUI view. After all, they're nothing more than a Swift struct conforming to a protocol. In the above code, you placed your views inside a &lt;code&gt;VStack&lt;/code&gt;, and each inside a &lt;code&gt;Button&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As opposed to UIKit's &lt;code&gt;UIButton&lt;/code&gt;, &lt;code&gt;Button&lt;/code&gt; is a completely blank view. All it does is make its contents touchable and manages button state changes. How the button looks is completely up to you. In the code above, you used &lt;code&gt;PrimaryButton&lt;/code&gt; and &lt;code&gt;SecondaryButton&lt;/code&gt; to display a button label. Instead of that, you could have used &lt;code&gt;Text&lt;/code&gt;, &lt;code&gt;Image&lt;/code&gt; or any other SwiftUI view.&lt;/p&gt;

&lt;p&gt;Currently, the buttons don't do anything. But, if you run the project and tap on the buttons, you'll notice they light up as you tap them. That animation is coming from &lt;code&gt;Button&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Earlier in this part of the course you used padding to space out views within a stack. If you want the space between each of the items to be the same, you can pass the &lt;code&gt;spacing&lt;/code&gt; parameter to a stack's initializer. The stack will then take care of the spacing for you. You can even use padding a spacing in tandem for those pixel-perfect designers among you!&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%2Fizoybo8y7r0zl1j2ylco.png" 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%2Fizoybo8y7r0zl1j2ylco.png" alt="Your first SwiftUI screen!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And with that, your welcome screen is done!  This now looks exactly like the original screenshot, giving the user some information about the app and a way to log in and register. Right now, these buttons don't do anything. In the next part of this SwiftUI course, you'll navigate to a login and registration screen!&lt;/p&gt;

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

&lt;p&gt;In the span of one part of this course, you went from having no app and no SwiftUI knowledge to building out your first full SwiftUI screen! With this knowledge and some googling, you now have the skills to build almost any static SwiftUI screen.&lt;/p&gt;

&lt;p&gt;You know about views, how to create them, lay them out and space them around. You also learned about adding and customizing text, creating buttons and displaying images.&lt;/p&gt;

&lt;p&gt;SwiftUI shows its power here: By learning a small number of tools you can build out any UI you can imagine. That's elegant, flexible design.&lt;/p&gt;

&lt;p&gt;Your layout knowledge doesn't need to end here, though. For the A-grade students among you, check out the WWDC session called "&lt;a href="https://developer.apple.com/videos/play/wwdc2019/237/" rel="noopener noreferrer"&gt;Building Custom Views with SwiftUI&lt;/a&gt;" which goes more in-depth into how the layout system works and some other tricks you can use.&lt;/p&gt;

&lt;p&gt;There's still much to learn! You now know how to make static UIs, but in the next part, you'll learn how to navigate to a login screen and manage the state for your UIs. Keep reading to build out the login screen of your app!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
    </item>
    <item>
      <title>SwiftUI: An Introduction</title>
      <dc:creator>marinbenc🐧</dc:creator>
      <pubDate>Mon, 23 Dec 2019 13:30:30 +0000</pubDate>
      <link>https://dev.to/cometchat/swiftui-an-introduction-1djh</link>
      <guid>https://dev.to/cometchat/swiftui-an-introduction-1djh</guid>
      <description>&lt;p&gt;Apple dropped a bombshell for developers on WWDC 19. Among a bunch of other things, they released SwiftUI — a whole new way of making iOS apps and the biggest change to iOS development since Swift came out. Say goodbye to storyboards, auto-layout or coding your UI by hand, SwiftUI is here to replace all of that. If this sounds good to be true, &lt;em&gt;you might be right&lt;/em&gt;. This introduction is here to show you what SwiftUI is all about, how it fits in the existing ecosystem and what it means for iOS developers.&lt;/p&gt;

&lt;p&gt;Whether or not you're brave enough to switch to SwiftUI now, the fact is that the future of iOS development is SwiftUI. Currently, SwiftUI is in the same place Swift was a couple of years ago, starting small with a handful of early adopters. But Apple's messaging is pretty clear: Just like Swift, SwiftUI will become the dominant framework in a couple of years.&lt;/p&gt;

&lt;p&gt;That's why learning SwiftUI, sooner rather than later, is a valuable (and marketable!) skill for any iOS developer and this introduction is here to get you started.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am creating this course in collaboration with CometChat, a modern chat platform to help you add chat to you Swift app. During the next few weeks, we’ll be releasing installments of our free SwiftUI course here on dev.to! In the course, you’ll dive deep into SwiftUI by building a real-world production-scale chat app, learning SwiftUI in a practical way, on a scale larger than a simple example app. Follow me to get notified of future parts of this course! You can also follow &lt;a href="https://twitter.com/cometchat" rel="noopener noreferrer"&gt;@CometChat&lt;/a&gt; on Twitter see the course of &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.cometchat.com" rel="noopener noreferrer"&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%2Favpunu4hqp1ut7enf5tq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How SwiftUI Works
&lt;/h2&gt;

&lt;p&gt;To see just &lt;em&gt;how&lt;/em&gt; different SwiftUI is from UIKit, let's look at a SwiftUI login screen.&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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1571999511056_Screenshot%2B2019-10-25%2Bat%2B12.31.47.png" 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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1571999511056_Screenshot%2B2019-10-25%2Bat%2B12.31.47.png" alt="A plain login screen written in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That screen is coded with the following code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import SwiftUI

struct ContentView: View {

  @State var email = ""
  @State var password = ""
  @State var error: String?

  var body: some View {
    NavigationView {
      VStack {
        TextField("Email", text: $email, onCommit: validate)
          .padding()
          .textFieldStyle(RoundedBorderTextFieldStyle())
          .keyboardType(.emailAddress)
        SecureField("Password", text: $password, onCommit: validate)
          .padding()
          .textFieldStyle(RoundedBorderTextFieldStyle())

        Button(action: login) {
          Text("Sign in")
        }.disabled(error != nil)

        error.flatMap {
          Text("Error: \($0)").foregroundColor(.red)
        }
      }.navigationBarTitle("Log In")
    }
  }

  func validate() { ... }
  func login() { ... }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Right now you might not understand everything that's going on in the code above — that's okay. Focus on how &lt;em&gt;much&lt;/em&gt; code there is. This is the whole UI. There are no additional storyboards, constraint setup code or &lt;code&gt;UIView&lt;/code&gt; subclasses. Even without knowing SwiftUI, you can kind of figure out what the screen looks like and what it does just by looking at the code.&lt;/p&gt;

&lt;p&gt;You can think of SwiftUI views as being split between two workers. The workers are each working on their own thing, and only indirectly impacting each other. The first worker renders the UI based on the current state. The other worker takes input from the user and changes the state.&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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1571999609728_Screenshot%2B2019-10-23%2Bat%2B13.01.18.png" 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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1571999609728_Screenshot%2B2019-10-23%2Bat%2B13.01.18.png" alt="How SwiftUI works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a SwiftUI &lt;code&gt;View&lt;/code&gt;, the state is a variable marked with &lt;code&gt;@State&lt;/code&gt;, while the view is a computed variable called &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView: View {
  @State var count = 0

  var body: some View {
    VStack {
      Button(action: { self.count += 1 }) {
        Text("Increment")
      }
      Text("Count: \(count)")
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can think of &lt;code&gt;body&lt;/code&gt; as a function from the state to the view. The &lt;code&gt;@State&lt;/code&gt; annotation tells SwiftUI to listen to changes of that variable. Whenever it changes, SwiftUI will call &lt;code&gt;body&lt;/code&gt; to re-render the view based on that new state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Body&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The syntax inside of &lt;code&gt;body&lt;/code&gt; might look strange, like a different language embedded into Swift. In reality, it's all just plain old Swift. There's no compiler magic or special exceptions for SwiftUI: &lt;em&gt;You&lt;/em&gt; could implement SwiftUI using plain Swift if you had enough time.&lt;/p&gt;

&lt;p&gt;The reason the syntax looks so strange is that it uses &lt;a href="https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544" rel="noopener noreferrer"&gt;implicit&lt;/a&gt; &lt;code&gt;[return](https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544)&lt;/code&gt;&lt;a href="https://forums.swift.org/t/se-0255-implicit-returns-from-single-expression-functions/22544" rel="noopener noreferrer"&gt;s&lt;/a&gt; and &lt;a href="https://github.com/apple/swift-evolution/blob/9992cf3c11c2d5e0ea20bee98657d93902d5b174/proposals/XXXX-function-builders.md" rel="noopener noreferrer"&gt;function builders&lt;/a&gt;, two Swift 5.1 features.&lt;/p&gt;

&lt;p&gt;Single-expression functions don't need a &lt;code&gt;return&lt;/code&gt; keyword, which is why, in the above example, &lt;code&gt;body&lt;/code&gt; can return a &lt;code&gt;VStack&lt;/code&gt; even if you don’t write  &lt;code&gt;return&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Function builders&lt;/em&gt; let you define functions that implicitly return an array as a list of expressions. For instance, if you had a builder for an array of integers, you could write a function like the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@NumbersBuilder
func build() -&amp;gt; [Int] {
  1
  2 + 2
  3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Swift will then create an empty array, take every &lt;strong&gt;top-level&lt;/strong&gt; expression in the function, evaluate then and add their results to the array, returning &lt;code&gt;[1, 4, 3]&lt;/code&gt; for the above example.&lt;/p&gt;

&lt;p&gt;Similarly, in the SwiftUI example above, &lt;code&gt;VStack&lt;/code&gt; is a struct that receives a function builder of &lt;code&gt;View&lt;/code&gt;s in its initializer. Because Swift lets us emit the round brackets around closures, the syntax looks like &lt;code&gt;VStack { ... }&lt;/code&gt;. Inside the curly braces, every top-level expression gets evaluated to a list of &lt;code&gt;View&lt;/code&gt;s (in this case containing &lt;code&gt;Button&lt;/code&gt;  and &lt;code&gt;Text&lt;/code&gt;) and added to a vertical stack view.&lt;/p&gt;

&lt;p&gt;If you remove all syntax sugar from the above &lt;code&gt;body&lt;/code&gt;, you'll end up with this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var body: some View {
  let button = Button(
    action: { self.count += 1 },
    label: { return ViewBuilder.buildBlock(Text("Increment")) })

  let countText = Text("Count: \(count)")

  return VStack(content: {
    return ViewBuilder.buildBlock(button, countText)
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It looks a lot messier, but you might get a better idea of what the code does this way.&lt;/p&gt;

&lt;p&gt;The reason I'm telling you this is because SwiftUI will look daunting at first. You'll also receive very opaque error messages that you that will make you scratch your head in confusion. Knowing that underneath it all lies familiar old Swift will illuminate a lot of these errors for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The counter screen example works without any additional code. You'll notice there's no "glue" code anywhere telling SwiftUI to update the counter label with the new text. That's because SwiftUI does that automatically.&lt;/p&gt;

&lt;p&gt;By annotating &lt;code&gt;count&lt;/code&gt; with &lt;code&gt;@State&lt;/code&gt;, SwiftUI knows to call &lt;code&gt;body&lt;/code&gt; to reload the view whenever &lt;code&gt;count&lt;/code&gt; changes.&lt;/p&gt;

&lt;p&gt;This &lt;em&gt;still&lt;/em&gt; isn't compiler magic, just plain Swift. The &lt;code&gt;@State&lt;/code&gt; annotation is made with a new Swift feature called &lt;a href="https://nshipster.com/propertywrapper/" rel="noopener noreferrer"&gt;property wrappers&lt;/a&gt;. Property wrappers are structs or classes that hold a single property and expose a setter and a getter, but when used they indistinguishable from a plain value.&lt;/p&gt;

&lt;p&gt;By incrementing &lt;code&gt;count&lt;/code&gt; (&lt;code&gt;count += 1&lt;/code&gt;), you're really calling the setter in the &lt;code&gt;State&lt;/code&gt; property wrapper. In other words, the following lines:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@State var count = 0
count += 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Can be de-sugared to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let countState = State(initialValue: 0)
countState.wrappedValue += 1 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;State&lt;/code&gt; has a defined setter for &lt;code&gt;wrappedValue&lt;/code&gt; that will tell SwiftUI to reload the view. Thankfully, you don't have to write all that. By using property wrappers, SwiftUI lets you use the state as a regular variable, reloading the view automatically on every change.&lt;/p&gt;

&lt;p&gt;You might notice an issue here. If we re-render the body every time a tiny change happens, we'll end up rewriting the whole UI every couple of seconds! Thankfully, SwiftUI &lt;strong&gt;only updates the views that need updating&lt;/strong&gt;. The view hierarchy has a tree-like structure, and you can compare the current tree of views with the next one. Only the nodes that are different (and their sub-nodes) need to be updated.&lt;/p&gt;

&lt;p&gt;The goal of SwiftUI is to let the system take care of more things, so you can focus on making the app you like.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Tenets of SwiftUI
&lt;/h2&gt;

&lt;p&gt;You'll hear a lot of buzzwords around SwiftUI, both from Apple and the community. To realize what SwiftUI means, it's important to unpack those buzzwords:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Composable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, SwiftUI is &lt;strong&gt;composable&lt;/strong&gt;. It doesn't separate views from view controllers, instead, your whole UI is made up of &lt;code&gt;View&lt;/code&gt;s. This gives you the flexibility to separate your code in any way you see fit. You can have one huge &lt;code&gt;View&lt;/code&gt; for your app, or have a huge hierarchy of small &lt;code&gt;View&lt;/code&gt;s. This also makes it easier to reuse stuff. Every &lt;code&gt;View&lt;/code&gt; can be placed inside every other &lt;code&gt;View&lt;/code&gt;, with no need for child view controllers or lifecycle management pains.&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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1572001105818_Screenshot%2B2019-10-25%2Bat%2B12.52.28.png" 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%2Fpaper-attachments.dropbox.com%2Fs_B4BD5BC1113396FE6C7C810B61229600F0589EE048E774B079748EDF04FD858D_1572001105818_Screenshot%2B2019-10-25%2Bat%2B12.52.28.png" alt="A composable View hierarchy in SwiftUI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This makes SwiftUI development &lt;strong&gt;incredibly easy for copy-and-paste development&lt;/strong&gt;. While seasoned developers might scoff at that sentence, the way people build apps these days is by searching for simple things like "how to make a button" and copying the code.&lt;/p&gt;

&lt;p&gt;I built a login screen this way in SwiftUI, without any previous knowledge, in 15 minutes. If I wanted to do that in UIKit, I'd have to spend days reading about Interface Builder, auto-layout and outlets before I could even start coding.&lt;/p&gt;

&lt;p&gt;Finding a working example and tweaking it to your needs is incredibly productive, and SwiftUI lets you do that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declarative&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Secondly, SwiftUI is &lt;em&gt;declarative&lt;/em&gt;. Instead of creating a storyboard or creating your UI by instantiating and setting up views, SwiftUI lets you use Swift code to &lt;em&gt;describe&lt;/em&gt; your UI. You tell SwiftUI, "I want a black view here, and a red view inside of it." SwiftUI then goes and draws those views for you. And it's all just plain Swift code.&lt;/p&gt;

&lt;p&gt;What's frustrating about Storyboards is that they're not code. Everything needs to be constant and pre-determined. You can't dynamically calculate a margin or hide a view based on some condition. In other words, &lt;strong&gt;there are no&lt;/strong&gt; &lt;code&gt;**if**&lt;/code&gt;&lt;strong&gt;s in a storyboard.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;However, the code inside SwiftUI's &lt;code&gt;body&lt;/code&gt; is plain Swift. That means that all of Swift's tools are available to you: You can use structs, classes, collections, loops and control blocks to write out your UI. If you want to show an empty state in your list, you can check if the list is empty and show that view, and otherwise show the list.&lt;/p&gt;

&lt;p&gt;By giving you the flexibility of Swift, your UI code becomes a lot simpler, and the tension between the Storyboard and your code disappears.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reactive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, SwiftUI is &lt;em&gt;reactive&lt;/em&gt;. If you want to change the color of a button in UIKit, you'd grab the button and directly set its color. SwiftUI doesn't offer this direct control. Instead, you'd have a state variable that defines button's color. You'd also have a different function that returns a new button based on this new variable. Whenever you change the state variable, SwiftUI will automatically call the latter function and draw the new button.&lt;/p&gt;

&lt;p&gt;This eliminates a whole class of bugs that come up as a result of a difference between your view controller's state and what's shown on the UI. By letting SwiftUI reload your views automatically, you know that your view's state is the &lt;strong&gt;single source of truth&lt;/strong&gt; for the view. This lets you focus on working only on the state, without having to think of what will happen in your view.&lt;/p&gt;

&lt;p&gt;This idea of separating working on your state and your view is a long-standing idea in the iOS community. It's the idea behind the most popular architectural patterns like MVP (Model and Presenter separated from the View), MVVM (Model and View Model separated from the View), VIPER and others. With SwiftUI, you get this separation out of the box.&lt;/p&gt;

&lt;p&gt;This combination of features in a single framework isn't new by a long shot. React, Vue.js and Angular — three of the most JavaScript UI frameworks already have these features. With frameworks like Electron, React Native, Jetpack Compose and Flutter, this approach to UI is already here on mobile, in huge apps like Instagram, Uber or Pinterest. This is &lt;strong&gt;well-trodden territory&lt;/strong&gt; and has proved itself to be one of the most productive ways to program UIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thinking SwiftUI
&lt;/h2&gt;

&lt;p&gt;By now you noticed that SwiftUI works a lot differently than UIKit. Just like you can't write Swift as you wrote Objective-C, you can't write SwiftUI like you wrote UIKit. SwiftUI requires a change of mindset.&lt;/p&gt;

&lt;p&gt;When looking at a login screen, an iOS developer will first think of a view controller containing two text views and a button. In SwiftUI, you'll instead think of three different &lt;code&gt;View&lt;/code&gt;s. First, you'll need a &lt;code&gt;View&lt;/code&gt; for the text view. Next, you'll need another &lt;code&gt;View&lt;/code&gt; for the button. Finally, you'll need a &lt;code&gt;View&lt;/code&gt; that will assemble two text views and the button.&lt;/p&gt;

&lt;p&gt;When working with SwiftUI, you'll stop thinking in terms of properties and methods, and start thinking in terms of state. A text view has a state variable that holds the text. Instead of changing &lt;code&gt;textView.text&lt;/code&gt;, you'll update the state. The state change will then trigger a call of the &lt;code&gt;body&lt;/code&gt; variable, where you'll return a new text field containing the new text.&lt;/p&gt;

&lt;p&gt;By starting simple and slowly building out a whole app, this type of thinking will become second-nature by the end of our SwiftUI course.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Hard is SwiftUI?
&lt;/h2&gt;

&lt;p&gt;I won't lie to you, &lt;strong&gt;SwiftUI is completely different than UIKit&lt;/strong&gt;. When I first started building an app in SwiftUI I had a little identity crisis. Here I was, an iOS developer who has worked on tens of apps, wrote and edited books about iOS, spoke at iOS meetups — struggling with centering a text field.&lt;/p&gt;

&lt;p&gt;Over time, though, I found my way around the different types of views. When I get stuck, I knew what to try and where to find the solutions. I realized that, even though my UIKit knowledge isn't of much use, I still understand Swift, the iOS ecosystem and programming. Thankfully, SwiftUI is nothing but Swift! Armed with these skills (and our course!), I'm sure you'll quickly get the hang of SwiftUI.&lt;/p&gt;

&lt;p&gt;That's where we come in. During the following few months, we'll be releasing a SwiftUI course that will teach you how to make a complete, production-level SwiftUI app. Read to the end of this article to find out more about the course!&lt;/p&gt;

&lt;h2&gt;
  
  
  What about UIKit?
&lt;/h2&gt;

&lt;p&gt;You can think of UIKit now as Objective-C a couple of years ago. Even though SwiftUI is the new hotness, it still stands on the shoulders of UIKit (and Objective-C, for that matter). That means that UIKit isn't going away soon.&lt;/p&gt;

&lt;p&gt;Slowly, over time, Apple will probably put more and more focus on SwiftUI, until eventually, SwiftUI will be the framework receiving new features instead of UIKit. Don't worry, though, you still have plenty of time.&lt;/p&gt;

&lt;p&gt;Speaking of which, the pragmatists among you might want to hold out a little bit until you convert your app to SwiftUI. Just like the early days of Swift, SwiftUI is young and not fully molded into shape. Some things that exist in UIKit are still just plain missing. As SwiftUI evolves and matures, expect a lot of changes and &lt;code&gt;View&lt;/code&gt; rewriting.&lt;/p&gt;

&lt;p&gt;That isn't to say you shouldn't learn SwiftUI. If you're an iOS developer, knowing SwiftUI (and knowing it early) can help you stand out among other, more conservative developers. Eventually, everybody doing iOS development will need people who know SwiftUI. Getting in early can be a competitive advantage for you or your company.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should I Use SwiftUI?
&lt;/h2&gt;

&lt;p&gt;You should &lt;em&gt;learn&lt;/em&gt; SwiftUI as soon as possible. But, should you convert or start making your app in SwiftUI? The answer is, as it is often, an unsatisfying “&lt;em&gt;it depends”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;SwiftUI is very young and the small SwiftUI community is only starting to grow. Some things that are available in UIKit don't yet exist in SwiftUI, and there are some kinks Apple still needs to work out. I expect SwiftUI to change a little bit in a year's time, which might not be the best thing to hear if you want to convert your whole app.&lt;/p&gt;

&lt;p&gt;If you're starting to make an app now and only want to support iOS 13, I'd strongly consider using SwiftUI as much as possible.&lt;/p&gt;

&lt;p&gt;If you already have an existing app, it might be more practical to build new views in SwiftUI (and convert a few existing smaller ones) and use UIKit and SwiftUI in tandem, slowly increasing the ratio of SwiftUI code over UIKit. John Sundell seems to agree with this thinking and has some good practical advice on &lt;a href="https://www.swiftbysundell.com/articles/shifting-paradigms-in-swift/" rel="noopener noreferrer"&gt;his blog post&lt;/a&gt; about how to mix and match SwiftUI with UIKit.&lt;/p&gt;

&lt;p&gt;If you decide to go full SwiftUI, be ready for some changes down the line. If you decide to not use SwiftUI at all, don't be surprised when Apple pulls the UIKit rug out from under you sooner than you expect. I suggest going right down the middle and gradually adopting SwiftUI as you go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get started!
&lt;/h2&gt;

&lt;p&gt;To help you master SwiftUI, we're working on a full SwiftUI course that we'll release over the coming few months.&lt;/p&gt;

&lt;p&gt;This SwiftUI course is designed for the practical developer. You'll learn SwiftUI by building our a real-world production-level chat app. You'll see the benefits and disadvantages of SwiftUI on a scale larger than a simple example app. You'll also learn how large SwiftUI apps can be structured and architected, as well as how to leverage other new frameworks like Combine to help you build your apps.&lt;/p&gt;

&lt;p&gt;While other courses and Apple's website offer great short examples, diving in deep is the only way to fully learn a framework, and that's what we'll do in this course.&lt;/p&gt;

&lt;p&gt;Here's how this course is structured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SwiftUI: An Introduction&lt;/strong&gt; (&lt;em&gt;You are here!&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build your first Swift UI screen&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;What's a &lt;code&gt;View&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Using Previews&lt;/li&gt;
&lt;li&gt;Managing the State&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Working with Lists in Swift UI&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Lists and Navigation&lt;/li&gt;
&lt;li&gt;Building the Chat Screen&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Build a chat app interface in SwiftUI for iOS&lt;/strong&gt;&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;State management with Combine&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;State and Binding&lt;/li&gt;
&lt;li&gt;Environment Objects&lt;/li&gt;
&lt;li&gt;Introduction to Combine&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Complete the SwiftUI chat app for iOS&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Using Combine for Networking&lt;/li&gt;
&lt;li&gt;Creating Combine Publishers&lt;/li&gt;
&lt;li&gt;Hooking everything up&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If you want to receive the next part of the course as soon as it comes out, follow me here, or check out the posts on &lt;a href="https://www.cometchat.com/blog/" rel="noopener noreferrer"&gt;CometChat's blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
    </item>
  </channel>
</rss>
