<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>SwiftUI 2.0: The Future is Declarative | Infinum</title>
		<atom:link href="https://infinum.com/blog/swiftui-2/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/swiftui-2/</link>
		<description>Building digital products</description>
		<lastBuildDate>Tue, 07 Apr 2026 19:14:13 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>8082https://infinum.com/uploads/2020/09/swiftUI-2-0.webp</url>
				</image>
				<title>SwiftUI 2.0: The Future is Declarative</title>
				<link>https://infinum.com/blog/swiftui-2/</link>
				<pubDate>Thu, 10 Sep 2020 12:25:00 +0000</pubDate>
				<dc:creator>Goran Brlas</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/swiftui-2/</guid>
				<description>
					<![CDATA[<p>Has SwiftUI overcome its initial shortcomings and brought significant improvements in the version 2.0?</p>
<p>The post <a href="https://infinum.com/blog/swiftui-2/">SwiftUI 2.0: The Future is Declarative</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-276"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Since its introduction last year, SwiftUI has piqued the interest of most Apple ecosystem developers with its “learn once, apply everywhere” approach. After playing around with it for a bit, we wrote an <a href="https://infinum.com/blog/swiftui-is-here-to-knock-uikit-out-of-its-shoes/">overview of SwiftUI itself</a>, as well as looked into how <a href="https://infinum.com/blog/combine-makes-swiftui-shine/">Combine fits in the picture</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	It looked promising and made UI programming really fun. However, its <strong>initial shortcomings and imposed minimal OS support version prevented it from ever fully taking off</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-99">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-100'
	>
	A more mature SwiftUI</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	Improvements that came during this year’s WWDC, along with the maturation of the toolkit itself, mean more and more teams are going to slowly make a switch to a new way of building cross-platform user interface layers that work across iOS, iPadOS, macOS, tvOS, and even watchOS, using one set of tools and APIs.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-109"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-105">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-106'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-107'
	>
	The shift to a more declarative programming paradigm is coming, and we need to be ready for it.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-112"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-110">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-111'
	>
	I’ve talked about this very same topic at the recent Shift Remote E05: MOBILE event, and if you’d like, you can check out the recording of that talk <a href="https://www.youtube.com/watch?v=VuLELGztayY&amp;feature=youtu.be&amp;t=8665">here</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-113">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-114'
	>
	<strong>Now, let’s see what SwiftUI promised, what it delivered, and where it’s going in the future</strong>. Grab a coffee, settle in and let’s begin.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-116">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-117'
	>
	Humble beginnings, not quite</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-119">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-120'
	>
	When Apple first announced SwiftUI, they backed it up with some big claims regarding the changes it was going to bring to the development world of the Apple platform. Here are some of them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-122">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-123'
	>
	They said that we would need to write <strong>less code</strong>.<br>Stuff like creating a <em>tableView</em> or a <em>collectionView</em> that before took a lot of boring, boilerplate code would become things of the past.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	After that came <strong>adaptability</strong>, in all its forms:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-128">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-129'
	>
	<li><strong>platform</strong> – our apps would behave as first class citizens on all Apple platforms, from our Macs all the way down to our iPhones and Apple watches. The code we write would adapt to take full use of their respective capabilities, e.g. elements like pickers would show up as scrolling wheels on iOS, but on macOS they would take the dropdown shape.</li><li><strong>light &amp; dark mode</strong> – by using features introduced in iOS 13 such as system colors, we could easily adapt our applications to light &amp; dark mode. I’ve actually written a <a href="https://infinum.com/blog/how-to-prepare-your-app-for-dark-mode-in-iOS-13/">handy how-to guide on adopting dark mode</a>. SwiftUI helps us here with the <em>@Environment</em> property wrapper which we could use to get the current environment value, as well as any updates to it.</li><li><strong>font scaling</strong> – fonts used by SwiftUI adapt to the scale that your users pick in the phone settings, and SwiftUI views like <em>Text</em> would in turn adjust their size to fit everything nicely.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-131">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-132'
	>
	Next things next. After adaptability improvements came something that would upgrade our development process, as well as increase the speed of our output – the ability to <strong>preview</strong> our UI at the same time as actually writing the code for it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	Technologies like Flutter or React Native had had this option for a while, and last year we were finally given a native alternative to the <em>build-install-run</em> dance that used to bite out a solid chunk of developers’ daily programming time. By using preview, the written code would automatically and immediately be seen in it, as well as all made changes. There was also an option to run a <strong>live preview</strong>, allowing for test user interaction or navigation testing, similarly to running the app in the Simulator/on a real device.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	Code &amp; preview combination also meant that we now had a <strong>single point of truth</strong> for our UI; checking out storyboard/xib files and/or code to find out who has overwritten whom and caused our UI bugs was gone, going, gone. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-140">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-141'
	>
	Btw, if you&#8217;d like to know more about those hardships, we&#8217;ve got you covered with our article on the long-term <a href="https://infinum.com/blog/storyboard-code-ui-building-ios/">UI-building dilemma of choosing between storyboards and code</a>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-145"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-143">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-144'
	>
	Finally, a native declarative way of writing apps for Apple platforms</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-148"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-146">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-147'
	>
	Finally, we got a <strong>native, declarative way</strong> of writing our applications for Apple platforms. Imperative approach stood the battle of time, but with general advancements in UI development, as well as the increase in app complexity our users expect, we needed something fresh which allowed for faster iterations, as well as easier state management.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-151"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-149">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-150'
	>
	All those things were supposed to make SwiftUI great – Apple wrapped them up in a shiny wrapper and told us <em>“Here you go, play around with it.”</em>. Naturally, presented with something new and unfamiliar, we did just that, and it didn’t take long before articles were touting this as the end of Objective-C, UIKit/AppKit and the be-all and end-all way to go.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-154"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-152">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-153'
	>
	However, with the honeymoon period over and our rose-tinted glasses off, we started seeing there was still a lot of room for improvement. Preview was not always working and used to crash consistently. New Xcode/Swift versions would break the existing SwiftUI code. Navigation would sometimes break, too. Tab management was not preserving the navigation stack. UI elements that we were used to in the UIKit world were missing their SwiftUI counterparts.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-157"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-155">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-156'
	>
	Creating simple UIs was fast and fun, but doing anything remotely complex or adjusting some existing elements like <em>Lists</em> usually meant dipping back into UIKit/AppKit, which kinda defeated the whole declarative purpose.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-160"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-158">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-159'
	>
	Last but not least, SwiftUI requires iOS 13 as the minimum OS version. For large scale applications, that meant leaving a significant part of their user-base behind, and that wasn’t really an option. However, it got us thinking about state management, and the way its declarative nature goes around solving issues that popped up.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-163"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-161">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-162'
	>
	State management (is hard)</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-166"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-164">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-165'
	>
	State management is hard.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-167"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-168">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2020/09/swiftUI-2-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="567"
															width="282"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Apple mail in action		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-170">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-171'
	>
	Let’s take the screen above from the Apple’s Mail app as an example. There’s a list of data, driven by some data models (in this case emails), as well as some extra navigation options, filters and actions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-173">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-174'
	>
	To create a screen like this, we need to connect our views with our models, and each one of these arrows seen in the image below represents a dependency.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-176"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-177">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2020/09/swiftUI-2-2-1400x840.webp				media='(max-width: 699px)'
				type=image/webp								height="840"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2020/09/swiftUI-2-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="960"
															width="1600"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Dependencies of a single screen		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-179">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-180'
	>
	As you can see, there are a lot of interconnected elements here since UI actions can update our models, and in turn they can update our UI. If you think this is complicated, bear in mind that this is just a single screen, and today our applications have a lot of screens which can share the same models, which makes the whole picture even more convoluted.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-182"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-183">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2020/09/swiftUI-2-3-1400x840.webp				media='(max-width: 699px)'
				type=image/webp								height="840"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2020/09/swiftUI-2-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="960"
															width="1600"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Dependencies between multiple screens		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-187"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-185">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-186'
	>
	This brings me back to the starting point of this section – state management is hard, and state management in large-scale applications that we usually build for our clients is getting harder each year. Supporting multiple device sizes, light &amp; dark modes, accessibility features, complex device features such as AR or Bluetooth, having a multiplayer mode and so much more – it all makes building apps in 2020 more challenging than ever. We work in bigger development teams, where each contributor comes with a different skill set that needs to be aligned in order to make a cohesive app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-190"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-188">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-189'
	>
	Sure, it can be easy to put a custom button on a screen, but how does it respond to accessibility? Does it adjust properly to different device sizes and orientations? Does it break if the customer changes their font scale? Is the state that button updates properly propagated to all the screens that require it? Now do that for not just a single button, but for all the UI elements you have on a screen. Not so easy now, is it?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-191">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-192'
	>
	As iOS developers, our job is to build applications that empower our users and adapt to their needs and potential disabilities. If we don’t, it can lead to a disappointing experience for our customers and can make the end product appear cheap and untrustworthy.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-198"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-194">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-195'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-196'
	>
	Remember, UI is all the end customer sees. If it sucks, they think the product sucks, no matter how good your backend &amp; foundational engineering work is.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-201"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-199">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-200'
	>
	The declarative solution</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-204"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-202">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-203'
	>
	With SwiftUI, we don’t need to worry about how our app is going to transition between all those different states. The age-old problem probably every single engineer has stumbled upon of <em>animating updates to this set of content based on a diff</em> – gone. We <em>just</em> need to write the code to describe how each state should look and the system figures out the rest. Like magic.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-207"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-205"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-206">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2020/09/swiftUI-2-4-1400x840.webp				media='(max-width: 699px)'
				type=image/webp								height="840"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2020/09/swiftUI-2-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="960"
															width="1600"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			SwiftUI&#8217;s declarative approach to state management		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-210"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-208">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-209'
	>
	SwiftUI offers a declarative approach to user interface design. As you compose a hierarchy of views, you also indicate data dependencies for the views. When the data changes, either due to an external event like a notification or because of an action taken by the user, SwiftUI automatically updates the affected parts of the interface. As a result, the framework performs most of the work traditionally done by view controllers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-211">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-212'
	>
	This unidirectional <strong><em>Action -&gt; State -&gt; View</em></strong> approach means that we no longer need to worry about keeping our UI and our data models in sync. Our state is the only one responsible for updating our <em>Views</em>, and <em>Actions</em> are in turn the only ones responsible of updating our <em>State</em>. Since our <em>Views</em> can’t update the <em>State</em> directly, the problem is automatically solved for us.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-216"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-214">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-215'
	>
	Paving the way forward</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-219"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-217">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-218'
	>
	Having gone over how SwiftUI started and the problems it aimed to solve, we should now cover the novelties announced at this year’s WWDC and see where SwiftUI is heading in the future.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-222"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-220">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-221'
	>
	New UI elements and options</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-225"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-223">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-224'
	>
	SwiftUI’s coverage of commonly used views has been greatly expanded this year, which is fantastic news both for developers who already have existing apps built with SwiftUI, and for people who are now getting started with the framework for the very first time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-228"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-226">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-227'
	>
	What most of us were looking forward to is the inclusion of alternative UI elements we were used to, and I think it’s fair to say that we weren’t disappointed with what we got:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-231"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-229">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-230'
	>
	<li><strong>TextEditor</strong> – offers a built-in way to add a larger text editing area to a UI, which is what makes it different from the TextField type that SwiftUI has been shipping with since its introduction. Wrapping UIKit’s UITextView is no longer needed, at least when looking to add a more basic set of text editing functionality to our applications</li><li><strong>ProgressView</strong> – platform-adaptable way of showing an appropriate default loading spinner, as well as an alternative version that can be used to show progress (e.g. for downloading some data)</li><li><strong>document-based apps support</strong> – we’ve been given two main types to work with: the <em>FileDocument</em> protocol to define what a document in our app looks like, and the <em>DocumentGroup</em> struct that gives us a default scene to let users create, open, and save documents.</li><li><strong>LazyHGrid &amp; LazyVGrid</strong> – collectionView alternative was something that was glaringly missing in the initial SwiftUI release, and these grids are what can be used to create similar layouts to what we were used to. They are container views that arrange their child views in a grid that grows horizontally and vertically respectively, creating items only as needed.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-234"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-232">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-233'
	>
	The concept of laziness is a big trend when it comes to this year’s SwiftUI changes, which is only solidified with the addition of <em>LazyHStack</em> and <em>LazyVStack</em> to their non-lazy counterparts. In general, implementations that are lazy don’t perform their work up-front, but rather at the time when it’s first needed. This can often lead to a ton of performance improvements, especially when dealing with larger collections and other heavy data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-237"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-235">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-236'
	>
	There are also a host of other new things which could be a whole blog post for themselves like <strong>matchedGeometryEffect, ScrollViewReader, ColorPicker, DisclosureGroup</strong> etc. Stay tuned to Capsized Eight, I guess?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-240"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-238">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-239'
	>
	New property wrappers</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-243"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-241">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-242'
	>
	Adding to the existing host of property wrappers, we got some new ones which will make our lives a bit easier:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-246"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-244">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-245'
	>
	<li><strong>@AppStorage</strong> – helps us read and write UserDefaults easily</li><li><strong>@ScaledMetric</strong> – scales values based on Dynamic Type settings</li><li><strong>@StateObject</strong> – safely creates reference types in views</li><li>and even more, such as <strong>@UIApplicationDelegateAdaptor, @Namespace, @SceneStorage</strong> etc.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-249"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-247">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-248'
	>
	On iOS 13, we had to use a UIHostingController (or NSHostingController on the Mac) to actually render out SwiftUI views, but now, our root view hierarchy can simply be embedded in a type conforming to the new <strong>App</strong> protocol, and by annotating that type with Swift’s new <strong>@main</strong> attribute, it’ll act as the entry point for our app – without the need for any app delegate or any other bootstrapping code:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">@main</span><span class="token">
</span></span><span class="line"><span class="token">struct BlogPostApp</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">App </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var body:</span><span class="token"> </span><span class="token" style="color: #d73a49;">some</span><span class="token"> Scene </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">WindowGroup</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">ContentView(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">struct ContentView</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">var body:</span><span class="token"> </span><span class="token" style="color: #d73a49;">some</span><span class="token"> View </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">Text(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Hello, SwiftUI 2.0!</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            .</span><span class="token">multilineTextAlignment(</span><span class="token">.</span><span class="token">center</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">            .</span><span class="token">padding(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-252">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-253'
	>
	Not just an alternative</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-255">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-256'
	>
	All of this brings me to my final point:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-262"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-258">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-259'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-260'
	>
	SwiftUI is not just an alternative; it is the future.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-265"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-263">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-264'
	>
	Apple has already started pushing in the spotlight by making it the only way to create widgets for the newest OS versions. MacOS has also started using it prominently in some of its redesigned features, like the new notification center.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-268"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-266">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-267'
	>
	The new unified design language Apple is pushing forward, combined with the fact that Apple Silicon Macs will be able to run iOS/iPadOS applications as well, means that having a single UI framework that can be used to develop for all platforms makes perfect sense.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-271"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-269">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-270'
	>
	Barely over a year old, SwiftUI is just getting started. Armed with all the new announcements and improvements, it’s already packing quite a punch and is set to be the future of development for all current, as well as future Apple platforms.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-274"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-272">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-273'
	>
	Prove me wrong?</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/swiftui-2/">SwiftUI 2.0: The Future is Declarative</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>