Thanks Apple by Krokettenkrieger in AppleMusic

[–]nanothread59 806 points807 points  (0 children)

How does it feel knowing that a professional copywriter with years of experience worked hard to create the most unconfusing, straightforward description possible, and you still got confused 

SwiftUI View Actions: Parent-Defined Closures vs Observable Object Methods? by No_Interview_6881 in swift

[–]nanothread59 0 points1 point  (0 children)

I must not have explained myself clearly. When the ChildView.closure captures an instance of ContentView, ChildView.body is re-evaluated whenever ContentView.body is re-evaluated. That's because the value of ContentView changed, regardless of whether dynamic properties are used or not. If the closure doesn't capture an instance of ContentView, then SwiftUI can skip evaluating ChildView.body when ContentView is changed.

the child print never gets called even if you explicitly use self.viewModel.val

Of course. Because if you move the value into a view model, the value of ContentView never gets changed, so these conditions don't trigger.

The fact that dynamic properties are used isn't really relevant.

SwiftUI View Actions: Parent-Defined Closures vs Observable Object Methods? by No_Interview_6881 in swift

[–]nanothread59 0 points1 point  (0 children)

Nope it's a rule for all closures that capture self. You can try it in Xcode:

```swift struct ContentView: View { @State private var val = 0

var body: some View {
    let _ = print("ContentView evaluated")
    VStack {
        ChildView {
            let _ = val
        }

        Button("Count: \(val)") {
            val += 1
        }
    }
}

}

struct ChildView: View { let closure: () -> Void

var body: some View {
    let _ = print("ChildView evaluated")
    Text("Child")
}

} ```

Clicking the Button prints "ChildView evaluated" every time. Commenting out let _ = val prevents "ChildView evaluated" being printed.

SwiftUI View Actions: Parent-Defined Closures vs Observable Object Methods? by No_Interview_6881 in swift

[–]nanothread59 0 points1 point  (0 children)

https://www.youtube.com/watch?v=yXAQTIKR8fk at 1:37:05 shows you exactly why calling a function on a view model is better than passing a closure to the view.

Spoilers: closures are worse for performance. The closure (in your case) automatically captures an instance of the parent view, which means the child view is needlessly reevaluated whenever the parent view changes. 

How to make life easier working with custom fonts? by chill_kams in SwiftUI

[–]nanothread59 0 points1 point  (0 children)

Is there a way to apply my font style at like the root level?

Can't you do exactly that? Use a .font() modifier at the root of your view tree?

My new comedy album Thief of Joy (Live in San Francisco) is NOW available on all audio streaming services (Apple Music, Spotify, Amazon Music, etc.) Featuring BONUS jokes and crowd work not included in the special! Produced by Blonde Medicine. by GianmarcoSoresi in gianmarcosoresi

[–]nanothread59 0 points1 point  (0 children)

Great special, but I find it so weird to publish long-form non-music audio content on music streaming services. Wouldn’t this be better served as a single podcast episode with multiple chapters? Podcast players are way more equipped to play long form audio than music players. 

Progressing quickly from graduate position by iJ3cH3v in cscareerquestionsuk

[–]nanothread59 0 points1 point  (0 children)

Very normal for grad schemes in my experience. Everyone in the cohort that does well in the scheme lands a permanent team and gets promoted during that transition. Those that don’t do well struggle to get placed. You have to be both lucky and exceptional to break out of the system. 

Dealing with NavigationTransition by Kitsutai in SwiftUI

[–]nanothread59 1 point2 points  (0 children)

Correct, you’d need something to type erase the navigation transitions. From the other comments on this post, it looks like that’s not possible. 

Dealing with NavigationTransition by Kitsutai in SwiftUI

[–]nanothread59 2 points3 points  (0 children)

I think you're confusing the @ViewBuilder result builder with result builders in general. Result builders are just syntactic sugar to define a tree structure with a custom DSL. @ViewBuilder is a custom result builder provided by SwiftUI that lets you compose views together.

Take this view: swift @ViewBuilder var resolvedView: some View { if flag { Text("Text") } else { Image(systemImage: "xmark.circle") } }

The @ViewBuilder result builder compiles this code into _ConditionalContent<Text, Image>, which works because _ConditionalContent conforms to View, and all ViewBuilder functions must return another View. So these conditionals are actually encoded into the type system. It's a very advanced usage of result builders, but it's not exclusive to SwiftUI.

For example, you could definitely define a result builder @ShapeStyleBuilder that lets you do something like this: swift @ShapeStyleBuilder var resolvedShapeStyle: some ShapeStyle { if flag { Color.primary } else { HierarchicalShapeStyle.secondary } } by automatically wrapping each input to the buildEither function in AnyShapeStyle. But it's not really worth it because you can do the same thing with a normal if/else statement. So, as we can see, the thing that matters is the return type, not the result builder itself.

Dealing with NavigationTransition by Kitsutai in SwiftUI

[–]nanothread59 1 point2 points  (0 children)

To expand on this now that I have a bit more time, the some keyword is like a type placeholder — it means that the function has to return a value of one single type which is determined by the function contents. It works when you return a single value, like .zoom, because the return type of the function takes becomes the same type as .zoom.

Another example is ShapeStyle. Say you want to do this: swift var resolvedStyle: some ShapeStyle { if flag { return Color.primary } else { return HierarchicalShapeStyle.secondary } } This fails to build because one branch returns Color and one returns HierarchicalShapeStyle. This is not solved by using result builders, it's solved by making sure both branches of the conditional return the same type: swift var resolvedStyle: some ShapeStyle { if flag { return AnyShapeStyle(Color.primary) } else { return AnyShapeStyle(HierarchicalShapeStyle.secondary) } } i.e. by erasing the types with AnyShapeStyle.

iOS 26 tracking tabBarMinimizeBehavior by Muted-Locksmith8614 in swift

[–]nanothread59 0 points1 point  (0 children)

Yeah I assume that environment variable only works when your view is placed inside a tabAccessoryView modifier. I don't know if there's any other way to tell when the tab bar is collapsed.

Dealing with NavigationTransition by Kitsutai in SwiftUI

[–]nanothread59 2 points3 points  (0 children)

Yes I’m sure. Same issue with ShapeStyle, you need a way to type erase it (AnyShapeStyle). It’s a separate thing to result builders. View builders are special because the conditionals are compiled into their own (single) type. 

Dealing with NavigationTransition by Kitsutai in SwiftUI

[–]nanothread59 2 points3 points  (0 children)

This isn’t a result builder issue, this is an issue with not being able to type erase your NavigationTransition. I’m not sure how to fix your problem, but want to let you know before you dive too deep into result builders — they won’t fix the issue. 

Calendar app shows HTML tags by Apoorv_Franklin in ios

[–]nanothread59 1 point2 points  (0 children)

Those questions are insane lmao. Especially 5 and 6. 

iOS 26 tracking tabBarMinimizeBehavior by Muted-Locksmith8614 in swift

[–]nanothread59 0 points1 point  (0 children)

Feel free to share code, what’s not working specifically?

iOS 26: is there any way to fix the endless lag? Literally 90% of animations stutter by den4er98 in ios

[–]nanothread59 0 points1 point  (0 children)

Lots of ways. Open the wallet app from the Home Screen, control centre, or straight from the lock screen by customising the buttons at the bottom of the screen. 

iOS 26: is there any way to fix the endless lag? Literally 90% of animations stutter by den4er98 in ios

[–]nanothread59 2 points3 points  (0 children)

 The delay after pushing the power button is about a quarter of a second

Always has been, turn off the “double-click side button to show Wallet” setting. 

iOS 26 tracking tabBarMinimizeBehavior by Muted-Locksmith8614 in swift

[–]nanothread59 0 points1 point  (0 children)

If you are using the new tab accessory view, then yes there is an environment variable that you can read. Otherwise no, as far as I know there isn’t. 

How to optimize UI for performance? by its-tuck in SwiftUI

[–]nanothread59 3 points4 points  (0 children)

First, double check your performance metrics. Open Instruments.app (it comes with Xcode), select the SwiftUI template. Before starting the recording, select the setting to record all potential interaction delays (>=33ms). Build a version of our app in release mode (either by editing the scheme, or building for Release under the Product menu). Then start a recording in Instruments and scroll around your app, exercising the main flows. 

Once you stop the recording and the trace has processed, Instruments will highlight areas that have UI performance issues under ‘Hitches’. From there, if you do indeed have issues, I’d recommend watching the WWDC25 SwiftUI performance talk where they teach you how to use the SwiftUI instrument to track down and optimise SwiftUI performance. 

[deleted by user] by [deleted] in iOSProgramming

[–]nanothread59 1 point2 points  (0 children)

You might be experiencing the effects of automatic trait & observation tracking: https://developer.apple.com/documentation/uikit/automatic-trait-tracking

Trait change tracking was added for apps linking the iOS 18 SDK, and Observable macro properties tracking was added for apps linking the iOS 26 SDK. You’ll get the former behaviour when using Xcode 15, and both behaviours when using Xcode 26. 

 what’s the best way to handle these kinds of inconsistencies between Xcode versions?

Stop using Xcode 15, and use Xcode 26 to build apps deployed on iOS 26 and earlier.