Tomorrow #Threads is coming to #Europe, and I'm more than a little bit curious, how it will play out.
That's where we stand @heiseonline regarding #Traffic from #X/Twitter and its main competitors right now. It's more quick and dirty than my other ones.
Keep in mind, that there's a substantial amount of traffic from #Mastodon, that we currently don't see (because of the #preview cutting of the URL): I'm pretty sure, that Mastodon has already overtaken #Twitter. #Bluesky is far, far behind.
In the hopes that it saves someone else some frustration…I just discovered you can't have an object in your project with the same name as one of the new Swift Macros. If you do you'll get the not super obvious error “No macro named X”.
I just ran into this because I had a view named "Preview" in my project which meant that if I tried to use any of the new #Preview options, my project wouldn't compile. Renaming my class completely fixed this.
That look longer than I'd like to admit to work out.
WWDC24 is right around the corner. Before the excitement and rush of what's to come, I want to share some navigation fun facts and tips. None of this is new, having been discussed previously in sessions, etc. From talking with developers, these are parts of the system that are often overlooked, or forgotten about #21DaysOfSwiftUINavigation#SwiftUI This is all running on macOS Sonoma 14.4, Xcode 15.3
NavigationLink(_ title:value:) is a "value-destination" link. Conceptually, it navigates to a value. From talking with developers, it's a misconception that this must be paired with a .navigationDestination(for:…) modifier, mapping directly to a view. As we saw in Day 3, it can drive List selection, mapping indirectly to a view.
This link often uses data-driven navigation (the opposite of fire-and-forget) — causing changes in client state like appending to a path seen here. #SwiftUI
Visiting first principles of NavigationStack for the next few tips. NavigationStack takes your app's data model, and transforms it into a stack of views. NavigationStack also supports fire-and-forget style navigation — these are standalone navigation actions that don't modify the client's state, i.e. the navigation path. The navigation system tracks that state internally for you. These are the simplest, so let's look at them first.
A video of a NavigationStack on watchOS. The stack pushes a view-destination navigation link. There is an onChange modifier for the navigation path, but it never prints anything because the client’s view of the path doesn’t change. Code: import SwiftUI struct Day6: View { @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { NavigationLink( destination: { RainbowSymbol() }, label: { Label("Navigate", systemImage: "compass.drawing") .font(.headline) }) }.onChange(of: path) { oldValue, newValue in print("path changed from (oldValue) to (newValue)") } } } private struct RainbowSymbol: View { var body: some View { Image( systemName: "cloud.rainbow.half.fill") .symbolRenderingMode(.multicolor) .symbolEffect( .variableColor.hideInactiveLayers, options: .repeating) .font(.system(size: 90)) } } #Preview { Day6() }
11 cont) Let's examine a navigation cycle. This example shows a navigation cycle that is a client bug. It's hard to spot why immediately. The Day11_Bad_Cycle view has an environmental dependency on MyEnvironmentKey. The value of MyEnvironmentKey is a closure. Closures are not equatable or comparable in Swift, the graph always has to assume they have changed value. Down below, the navigationDestination captures self by means of localState! When I tap push, the app freezes up 😮 #SwiftUI
11 final) In this version, I've wrapped the closure up in a Equatable Box. For a proof-of-concept, I use the @Namespace property wrapper to establish identity, given that I know that closure values identity is tied to the Namespace.The cycle is solved. The takeaway, make your environment values Equatable when possible, and when you can't, don't capture them as part of .navigationDestinations #SwiftUI
Shout out to a particular follower who knows where they are who filed quality FBs about this.
12 final) Given the size classes and interactions supported, fixing the sidebar is a rare, and currently unsupported (FBs welcome). On iPad in certain size classes users can drag from the leading edge to reveal the sidebar. Lest we forget the iPad mini in portrait where a fixed sidebar would feel cramped. And lest we really not forget this peek interaction on macOS #SwiftUI#21DaysOfSwiftUINavigation
An Xcode Previews window showing a macOS preview of a NavigationSplitView. Hovering the mouse some 5-10 points from the leading edge of the window reveal a peek of the sidebar. The user can grab the peeking sidebar and drag it open from a collapsed state. import SwiftUI struct Day12: View { var body: some View { NavigationSplitView { List { ForEach(0...10, id: .self) { i in NavigationLink("Option (i)", value: i) } } } detail:{ ContentUnavailableView( "Make your selection", systemImage: "circle.hexagongrid.fill") .symbolRenderingMode(.multicolor) .symbolEffect(.pulse, options: .repeating) } } } #Preview { Day12() }
macOS supports Cmd-click deselect out of the box. This works with value-destination and view destination links. You'll notice the view-destination link’s (Settings) selection is cleared when the environmental action dismiss is called from the detail view #SwiftUI#21DaysOfSwiftUINavigation
macOS Xcode Previews showing a basic NavigationSplitView. The 3 options in the sidebar as successively clicked and Command-clicked, which dismisses the presented view. Additionally, a button that calls the dismiss action form the detail column will also dismiss the presented view and clear selection. import SwiftUI struct Day13: View { var body: some View { NavigationSplitView { List { NavigationLink(value: "House") { Label("Home", systemImage: "house") } NavigationLink(value: "Profile") { Label("Profile", systemImage: "person") } NavigationLink { DismissibleView() } label: { Label( "Settings", systemImage: "gear") } } .navigationDestination(for: String.self) { str in if str == "House" { Color.accentColor } else { Color.mint } } } detail: { Text("No selection") } } } struct DismissibleView: View { @Environment(.dismiss) var dismiss var body: some View { ZStack { Color.gray Button("Dismiss") { dismiss() } } } } #Preview { Day13() }
List selection can drive navigation pushes. You can populate the selection binding with a value-destination NavigationLink, or, any other way you would normally populate it. #21DaysOfSwiftUINavigation#SwiftUI
A video showing a compact NavigationSplitView on iPhone Previews next to a code sample. The preview shows a list of with 4 elements, 3 navigation links, and 1 Text row. All 4 rows get a grey highlight when active. The non-navigation link row, the simple tagged Text, has no chevron, but still highlights gray in sync with the push progress. Code: import SwiftUI enum Sports: String, Hashable { case pickleball case dance case archery case volleyball } struct Day1: View { @State private var selection: Sports? var body: some View { NavigationSplitView { VStack { List(selection: $selection) { NavigationLink("Pickleball", value: Sports.pickleball) NavigationLink("Dance", value: Sports.dance) NavigationLink("Archery", value: Sports.archery) Text("Volleyball").tag(Sports.volleyball) } } } detail: { if let selection { VStack { Text(selection.rawValue.capitalized(with: .current)) Image(systemName: "figure.(selection.rawValue)") } } else { ContentUnavailableView( "Make a selection", systemImage: "volleyball") } } } } #Preview { Day1() }
Last November we had the opportunity to attend an exclusive twenty-minute screening of ‘Dune: Part II’, the highly anticipated second installment of the monumental adaptation of Frank Herbert’s science fiction classic that Denis Villeneuve is carrying out. Of course, it is early to give an opinion, but we can assure that...
Viele schwören bereits auf die Beere, aber die wissenschaftlichen Belege waren bisher widersprüchlich. Nun gibt es dazu Neuigkeiten. Und die gucken wir uns mal genauer an.
This episode will drop in a couple of hours, honestly, probably after I’m live on accessible media Inc today at 11:00 AM PT. @damashe and I had a blast on Saturday recording, and here's how the episodes gonna start. Yes, I forgot to fix the playback rate! Don't judge me… #TechnicallyWorking#Podcasting#Audio#Preview.
PSA: if you're having issues with the #WWDC2023 "Build an app with #SwiftData" session similar to:
CompileDylibError: Failed to build ContentView.swift
Compiling failed: main actor-isolated let 'previewContainer' can not be referenced from a non-isolated context
Replacing the #Preview macro with the old-style preview syntax resolves the issue. (I don't have macOS 14 so I'm running the preview on iOS and it looks weird with the frame so I removed it. Added a frame version if you want it.)
I wasn't aware that you could use the new #Xcode Previews feature, known from #SwiftUI, and the new #Preview macro in particular, to show UIKit views, too!
We have seen 20 minutes of 'Dune II' with Villeneuve and we have good news: the expectation is more than justified (www.ruetir.com)
Last November we had the opportunity to attend an exclusive twenty-minute screening of ‘Dune: Part II’, the highly anticipated second installment of the monumental adaptation of Frank Herbert’s science fiction classic that Denis Villeneuve is carrying out. Of course, it is early to give an opinion, but we can assure that...
Lazarus Trailer | Toonami | adult swim (www.youtube.com)
Directed by Shinichirō Watanabe. Action sequences directed by Chad Stahelski. Produced by Sola Entertainment. Animation by MAPPA.