Attribute Graph (Part 6)
We extend our attribute graph to compute a display list containing the frames of all views.
Episode 434 · Dec 20
We explore Apple's new declarative UI framework.
167 Episodes · 58h12min
We extend our attribute graph to compute a display list containing the frames of all views.
Episode 434 · Dec 20
We construct the attribute graph for a simple SwiftUI example and step through the updates of the graph in response to changing inputs.
Episode 433 · Dec 13
We use Graphviz to visualize the attribute graph and add snapshots to step through the evaluation process.
Episode 432 · Dec 06
We make sure to recompute nodes in the graph that are marked dirty.
Episode 431 · Nov 29
We automatically add edges in the attribute graph and invalidate edges and nodes when necessary.
Episode 430 · Nov 22
We start to work on a reimplementation of SwiftUI's attribute graph.
Episode 429 · Nov 15
We turn the specific spray effect into a generic particle system and add a second effect.
Episode 423 · Oct 04
We make sure to garbage collect old particles and to pause and resume the timeline view.
Episode 422 · Sep 27
We combine the canvas-based drawing from last episode with a keyframe timeline to control the particles.
Episode 421 · Sep 20
We improve the performance of the particle effect by rendering the particles in a canvas view.
Episode 420 · Sep 13
We make our particle effect more flexible by combining it with a keyframe timeline.
Episode 419 · Sep 06
We start building a particle effect, using transitions as the first approach.
Episode 418 · Aug 30
We make our lazy vertical stack implementation more generic to support other kinds of vertical layouts.
Episode 417 · Aug 16
We continue to work on our custom lazy stack implementation and add support for preferred spacing.
Episode 416 · Aug 09
We try to re-implement a lazy vertical stack based off last week's experiments.
Episode 415 · Aug 02
We investigate SwiftUI's new group APIs for building custom lazy container views.
Episode 414 · Jul 26
We finish the bento layout by adding spacing and fixing a crash.
Episode 413 · Jul 19
We reimplement our bento layout on top of SwiftUI's layout protocol.
Episode 412 · Jul 05
We use the new Group API to turn our bento view into a custom container.
Episode 411 · Jun 28
We start implementing a bento layout using two different approaches.
Episode 410 · Jun 21
We discuss some subtleties around SwiftUI's view updates with regard to environment and preference changes.
Episode 409 · Jun 14
We automatically position the tooltips depending on the available space around the anchor view.
Episode 408 · Jun 07
We implement a custom tooltip API that only shows one tooltip at a time.
Episode 407 · May 31
We show how to detect which views in a lazy stack are currently onscreen.
Episode 406 · May 24
We use a custom animation to manually control the progress of animations using a slider.
Episode 405 · May 17
We implement the picker animation from the last episode using three more preference-based techniques.
Episode 404 · May 10
We build a picker with an animated underline using alignment and the matched geometry effect.
Episode 403 · May 03
We implement a wobble animation using a phase animator and the Animatable API.
Episode 402 · Apr 19
We use anchors and preferences to position the badges on top of all icons.
Episode 401 · Apr 12
We implement a badge view that scales with the content and position it using alignment.
Episode 400 · Apr 05
We reimplement SwiftUI's default button style to better understand its behavior.
Episode 399 · Mar 29
We add the fill content mode to our conditional aspect ratio layout and make sure it can handle nil proposals.
Episode 398 · Mar 22
We implement a custom version of SwiftUI's aspectRatio modifier that can be enabled or disabled.
Episode 397 · Mar 15
We add a hover effect to the legend view, highlighting the legend labels, as well as the views they point to.
Episode 392 · Feb 09
Building on the previous episode, we improve the horizontal alignment of the legend labels.
Episode 391 · Feb 02
We build a legend view using anchors and preferences.
Episode 390 · Jan 26
We create a pattern image shape style from a SwiftUI view.
Episode 389 · Jan 19
We improve the keys used to distinguish multiple tweakable values and add a tweakable container view.
Episode 388 · Jan 12
We add custom editors for tweakable values, simplifying our code at the same time.
Episode 387 · Jan 05
We make our tweakable helper generic so that we can adjust any type of value.
Episode 386 · Dec 22 2023
We discuss the basic approach to implementing tweakable values in SwiftUI.
Episode 385 · Dec 15 2023
We try to improve the performance and energy usage of the marquee view — with mixed results.
Episode 377 · Oct 20 2023
We add smooth velocity transitions to our marquee component and clean up the code.
Episode 376 · Oct 13 2023
We change our marquee animation to a tick-based approach and add a drag gesture.
Episode 375 · Oct 06 2023
We start building a marquee component using SwiftUI's timeline view.
Episode 374 · Sep 29 2023
We implement Catmull-Rom splines to interpolate smoothly between multiple cubic keyframes.
Episode 373 · Sep 22 2023
We add automatic smooth transitions between linear and cubic keyframes.
Episode 372 · Sep 15 2023
We implement the start and end velocity parameters for cubic keyframes.
Episode 371 · Sep 08 2023
We integrate our custom Bézier function from last episode to implement cubic keyframes.
Episode 370 · Sep 01 2023
We start implementing cubic keyframes by defining our own Bézier function.
Episode 369 · Aug 25 2023
We use a timeline view to animate views using our own keyframe implementation.
Episode 368 · Aug 18 2023
We implement the keyframe timeline type and add the possibility of having multiple keyframe types.
Episode 367 · Aug 11 2023
We reimplement SwiftUI's new keyframe-based animations, starting with linear keyframes.
Episode 366 · Aug 04 2023
We continue the macro implementation with generating getters and setters for the observed properties.
Episode 365 · Jul 28 2023
We implement a macro to automatically generate the code necessary for observation.
Episode 364 · Jul 21 2023
We make one-time observation calls work by working with observer IDs.
Episode 363 · Jul 14 2023
We begin reimplementing Swift's new observation mechanism by tracking access to observable objects.
Episode 362 · Jul 07 2023
We explore multiple ways to draw dotted lines between two points in SwiftUI.
Episode 356 · May 19 2023
We refactor our connecting lines code, disentangling the anchor logic from the content.
Episode 355 · May 12 2023
We use SwiftUI's anchors to draw connecting lines between multiple views in the view hierarchy.
Episode 354 · May 05 2023
We refactor our anchor implementation to support transforms like scaling and rotation.
Episode 353 · Apr 28 2023
We continue the anchor implementation, adding support for point anchors.
Episode 352 · Apr 21 2023
We reimplement SwiftUI's anchors to better understand what they do, starting with the bounds anchor.
Episode 351 · Apr 14 2023
We add support for vertical alignment to our Layout protocol-based Flow layout implementation.
Episode 350 · Apr 07 2023
To conclude this series, we render the result of our attributed string builder to a PDF file.
Episode 342 · Feb 10 2023
We add support for Markdown and make it styleable using a custom stylesheet.
Episode 341 · Feb 03 2023
We add support for images and SwiftUI embeds to our attributed string builder.
Episode 340 · Jan 27 2023
We add modifiers to apply various kinds of attributes and integrate Swift syntax highlighting.
Episode 339 · Jan 20 2023
We refactor the attributed string builder to support joining with a configurable separator.
Episode 338 · Jan 13 2023
We begin implementing an attributed string builder to replace the legacy infrastructure for rendering our books.
Episode 337 · Jan 06 2023
We make sure to restore the scroll position when switching tabs while keeping the picker stationary.
Episode 336 · Dec 23 2022
We use our sticky modifier to implement a tabbed scroll view with a sticky picker.
Episode 335 · Dec 16 2022
We improve our sticky header implementation with a nicer API and a subtle bug fix.
Episode 334 · Dec 09 2022
We implement a sticky modifier that makes views in a scroll stick to the top.
Episode 333 · Dec 02 2022
We use an animatable view to control the staggered animation with one common timing curve.
Episode 332 · Nov 25 2022
We use SwiftUI's semi-private variadic view API to create a better interface for our staggered animations.
Episode 331 · Nov 18 2022
We investigate different ways to create staggered animations, starting with delayed animations.
Episode 330 · Nov 11 2022
We clean up the async image caching code from the last episode to end up with a nicer interface.
Episode 329 · Nov 04 2022
We look at two different ways of improving the caching behavior of our AsyncImage implementation.
Episode 328 · Oct 28 2022
We create two versions of our async image implementation for more control over the data's lifetime.
Episode 327 · Oct 21 2022
We tackle the shape of the notch, make the clock auto update, and add the Home indicator.
Episode 326 · Oct 14 2022
We build a view modifier to make any view look like it’s rendered within an iPhone simulator.
Episode 325 · Oct 07 2022
We work on the accessibility of our custom stepper component.
Episode 324 · Sep 30 2022
We make the custom stepper styleable via the environment and create a hold-to-increment/decrement stepper style.
Episode 323 · Sep 23 2022
We introduce a stepper style protocol that allows us to create a wide range of appearances for our custom stepper.
Episode 322 · Sep 16 2022
We start building a custom stepper component and make it adapt to SwiftUI's control size.
Episode 321 · Sep 09 2022
We’re joined by Kasper to take a look at building custom components, beginning with exploring SwiftUI's built-in component styling.
Episode 320 · Sep 02 2022
We use the layout inspection wrapper from the last episode to examine how HStack's layout works.
Episode 319 · Aug 26 2022
We use SwiftUI's new Layout protocol to inspect the proposed and reported sizes in the layout process.
Episode 318 · Aug 19 2022
On selection of a search result, we jump to the relevant page and highlight the search term.
Episode 317 · Aug 12 2022
We add a search field to our SwiftUI workshop app and prepare the content to be searchable.
Episode 316 · Aug 05 2022
We add a search field to our SwiftUI workshop app and prepare the content to be searchable.
Episode 315 · Jul 29 2022
We clean up the code of the last few episodes by splitting our large view into smaller parts.
Episode 314 · Jul 22 2022
We implement some vector math to calculate the initial animation velocity from the drag gesture.
Episode 313 · Jul 15 2022
We lay the foundation for using a spring animation with the initial velocity for the drag gesture.
Episode 312 · Jul 08 2022
We add a drag gesture to close the detail view when it's being pulled down.
Episode 311 · Jul 01 2022
We add smooth animations from the photo grid to the detail view and back.
Episode 310 · Jun 24 2022
We start to build a photo grid view like in the stock Photos app, including gestures and transitions.
Episode 309 · Jun 17 2022
We take a first look at SwiftUI's new Layout protocol and integrate the flow layout we previously built.
Episode 308 · Jun 10 2022
We build a UI for creating chains of async algorithms and visualizing the results.
Episode 307 · Jun 03 2022
We refactor our code to support combining multiple async algorithms.
Episode 306 · May 27 2022
We add support for more algorithms, like zip and combineLatest, and clean up our code.
Episode 305 · May 20 2022
We add drag gestures to make the input streams interactive.
Episode 304 · May 13 2022
We transform arrays of events into async streams, run the merge algorithm on them, and visualize the result.
Episode 303 · May 06 2022
We start a new project to visualize the algorithms from the new Swift Async Algorithms package.
Episode 302 · Apr 29 2022
We use type-level programming to specify the alignment for each level of the tree diagram separately.
Episode 293 · Feb 25 2022
We use a custom alignment ID to control the positioning of parent nodes in our tree.
Episode 292 · Feb 18 2022
We prepare a tree diagram view in SwiftUI to experiment with advanced alignment techniques.
Episode 291 · Feb 11 2022
We show how animations in SwiftUI are implemented using transactions.
Episode 285 · Dec 17 2021
We detect the dates in our graph that are onscreen and use this to control a date picker.
Episode 280 · Nov 12 2021
We refine our graph view and add the ability to programmatically control the scroll view.
Episode 279 · Nov 05 2021
We start building a scrolling graph view that can display large amounts of data smoothly.
Episode 278 · Oct 29 2021
We finish our reimplementation of the matched geometry effect and discuss the discrepancies between SwiftUI's variant and ours.
Episode 260 · Jun 25 2021
We continue to work on our matched geometry implementation, adding the ability to the position as well as the size.
Episode 259 · Jun 18 2021
We look at SwiftUI's new AsyncImage API and reimplement it using async/await.
Episode 258 · Jun 11 2021
We start reimplementing SwiftUI's matched geometry effect to gain a better understanding of how it works.
Episode 257 · Jun 04 2021
We complete the pinch to open and pinch to close transitions from the last episode.
Episode 256 · May 28 2021
We combine magnification gestures with matched geometry effects to create smooth transitions.
Episode 255 · May 21 2021
We look at a technique similar to SwiftUI's ScrollViewReader to access the underlying MKMapView of a SwiftUI map.
Episode 254 · May 14 2021
We revisit our SwiftUI flow layout implementation from 1.5 years ago and write a simpler and more correct version.
Episode 253 · May 07 2021
We implement a row of buttons with equal widths and dynamic content based on the available space.
Episode 243 · Feb 26 2021
We implement a horizontal bar chart with labels at both ends of the bars.
Episode 242 · Feb 19 2021
We implement a real-world layout that looks simple but is not so simple in SwiftUI.
Episode 241 · Feb 12 2021
We create a wrapper view to easily test animations with previews.
Episode 240 · Feb 05 2021
We refactor our SwiftUI views to be testable in previews without mocking the model.
Episode 239 · Jan 29 2021
We provide the current slide number and total slide count via the environment and display them in the footer.
Episode 222 · Sep 25 2020
We add custom animations and use SwiftUI's matched geometry effect for animations between slides.
Episode 221 · Sep 18 2020
We create a wrapper view for slide headers that allows us to style all headers via the environment.
Episode 220 · Sep 11 2020
We scale our slides to fit any screen size and use SwiftUI Previews to render previews of all slides.
Episode 219 · Sep 04 2020
We implement a custom function builder to enable writing slides with the same syntax as SwiftUI views.
Episode 218 · Aug 28 2020
We start building a SwiftUI library for creating presentation slides.
Episode 217 · Aug 21 2020
We rebuild the model layer with structs instead of classes and use bindings to provide mutable access to the views.
Episode 202 · May 08 2020
We use published properties and property observers to clean up our model code, and we fix some issues on the iPad.
Episode 201 · May 01 2020
We take a callback-based model API and refactor it into an observable object.
Episode 200 · Apr 24 2020
We create a lazy wrapper for observable objects and use dynamic member lookup to ease its use.
Episode 199 · Apr 17 2020
We wrap a UIKit alert in a SwiftUI-like API to present an alert with a text field.
Episode 198 · Apr 10 2020
We continue working on the recording and playback screens while reusing existing model and helper classes from the MVC app.
Episode 197 · Apr 03 2020
We start to implement the MVC sample app from our App Architecture book in SwiftUI reusing the original model.
Episode 196 · Mar 27 2020
We wrap an MKMapView, using a diff on the annotations to properly animate insertions and removals.
Episode 195 · Mar 20 2020
We create a view that automatically scales a text view to fill the available space.
Episode 194 · Mar 13 2020
We add labels to the analog clock face, and we make it configurable to reuse it for counting the minutes.
Episode 193 · Mar 06 2020
We add lap times to the model, show them in a list, and highlight the shortest and longest laps.
Episode 183 · Dec 20 2019
We add the data model for the stopwatch to make it functional.
Episode 182 · Dec 13 2019
We enable our stopwatch buttons to self-size to fit their labels.
Episode 181 · Dec 06 2019
We use a custom button style to imitate the appearance of the stopwatch buttons on iOS.
Episode 180 · Nov 29 2019
We refactor our use of geometry readers and preferences to make our code more expressive.
Episode 179 · Nov 22 2019
We implement the drop functionality and work around several obstacles we encounter along the way.
Episode 178 · Nov 15 2019
We make our shopping cart interactive by adding drag and drop.
Episode 177 · Nov 08 2019
We use a view modifier with local state to animate views onto the screen.
Episode 176 · Nov 01 2019
We use anchors, preferences, and transitions to animate items from a grid into a cart.
Episode 175 · Oct 25 2019
We examine SwiftUI's animation curves using a custom view modifier.
Episode 174 · Oct 18 2019
We explore SwiftUI's rendering and animation model while building a shake animation.
Episode 173 · Oct 11 2019
We use drag gesture recognizers to add reordering capabilities to our SwiftUI collection view.
Episode 169 · Sep 13 2019
We implement single-line and flow layouts for our SwiftUI collection view.
Episode 168 · Sep 06 2019
As a first step toward a collection view, we enable child views to communicate their sizes to a parent view.
Episode 167 · Aug 30 2019
We further refine the animation from last episode and refactor it using a geometry effect.
Episode 166 · Aug 23 2019
We start building a custom animation of a shape that moves along a path.
Episode 165 · Aug 16 2019
We experiment with paths and shapes to create a triangular preview badge.
Episode 164 · Aug 09 2019
We integrate Apple's web authentication framework to enable logging in with GitHub and then store the credentials using a keychain property wrapper.
Episode 163 · Aug 02 2019
We create a two-way binding from the play position of the video player to a bindable model object.
Episode 162 · Jul 26 2019
We integrate an AVPlayerViewController, expose its play state as a binding, and use a SwiftUI view as an overlay.
Episode 161 · Jul 17 2019
We look at different ways to load data from the network less eagerly.
Episode 160 · Jul 12 2019
We explore different approaches to passing data around in our SwiftUI app.
Episode 159 · Jul 05 2019
We start building a Swift Talk app using SwiftUI.
Episode 158 · Jun 28 2019
We integrate the tiny networking library into a SwiftUI project and wrap AppKit's progress indicator in a SwiftUI view.
Episode 157 · Jun 21 2019
We build a simple currency converter to experiment with SwiftUI's state-driven view updates.
Episode 156 · Jun 14 2019