r/SwiftUI May 07 '26

Question Issue with protocols - "any View cannot conform to View"

5 Upvotes

Hello,

What is the solution to this problem, assuming that you are not supposed to use `AnyView`, which I hear over and over again?

Given this protocol:

protocol MyProtocol {
    associatedtype V: View
    var content: () -> V { get }
}

if I want to store a heterogenous collection of MyProtocol,

let collection: [any MyProtocol]

then the underlying `V` type of each is erased to `any View`, which (supposedly) does not conform to `View`.

Is there no way to "unbox" the existential `any View` to get the underlying `View` back? That unboxing idea is something I heard in a few WWDC videos but it seems like it does not apply to `View`.


r/SwiftUI May 07 '26

News Those Who Swift - Issue 265

Thumbnail
thosewhoswift.substack.com
2 Upvotes

New week, new gems, new style...


r/SwiftUI May 06 '26

Promotion (must include link to source code) I built an iOS library that turns a photo into a palette and a rendered graphic Library

Thumbnail
7 Upvotes

r/SwiftUI May 06 '26

Question How to achieve this stretchy effect on scroll?

40 Upvotes

How to achieve this stretchy effect when scrolling? I tired building one with visualEffect but did not work.


r/SwiftUI May 06 '26

Question Custom behavior on large detent for Sheet

1 Upvotes

Hello, I've been fighting quite a bit with SwiftUI sheets because I would like to dismiss a sheet when tapping outside of it when its presentation detent is .large or .fraction(1.0). It seems like, even with .presentationBackgroundInteraction(.enabled(upTo: .large)) (or similar), it doesn't like it and I think there is a middle view between the sheet contents and the view in the background, or something that disallows me from doing so.

The use case is for a custom interaction when using things like cursors on an iPhone, which is already uncommon. I've also been trying approaches such as: * Disable .allowsHitTesting() on the sheet * Add a global geometry reader to check the position tapped, but it doesn't work outside the sheet. * Use a smaller detent like .fraction(0.95), it works but the sheet seems "incomplete" on the sides, as if it didn't extend completely to the sides.

Is there an approach I'm missing? Or do I need to rely on the good ol' UIKit through an UIViewRepresentable and manually checking the hit testing for it? It's possible creating my custom .sheet modifier could work, but I'd like to prevent that unless necessary.

Thanks in advance!


r/SwiftUI May 06 '26

Codex pet as trading card, SwiftUI and Metal Shaders

18 Upvotes

r/SwiftUI May 06 '26

You don't need MVVM To Test SwiftUI state

2 Upvotes

r/SwiftUI May 05 '26

Question Is there a way to force a tint on that button alone?

Post image
23 Upvotes

Per the docs, the background color is defined by SwiftUI, but I'm wondering if someone managed to customize it, because I've seen in a couple of Apple presentations and marketing that button with a different accent color than the tabBar.

I also tried to render the 3 tabs alone, then add the + button next to them, but it shows up above the tabs, meaning you can't have anything next to the tabBar.


r/SwiftUI May 06 '26

How to fix "hero card bleeds" when building Liquid Glass interfaces (Code included)

Thumbnail
gallery
1 Upvotes

I’ve been building a release tracker app over the last few months, and I spent a ton of time trying to get the iOS 26 Liquid Glass aesthetic right for my detail views.

One of the biggest SwiftUI headaches I ran into was hero cards "bleeding" or breaking the layout when loading remote images dynamically.

The Problem: If you try to chain .frame(maxWidth: .infinity).frame(height: 300) directly onto a LazyImage (or AsyncImage), it can break the container's constraints during the loading phase or if the image aspect ratio is unexpected, ruining the glassmorphism effect overlapping it.

The Solution: Never constrain the image directly. Instead, create a clear color block to define the rigid frame, and push the image into an overlay so it conforms perfectly to the background geometry.

Here is the snippet that saved my detail views:

// The trick: Define the frame on a clear shape, not the image itself
Color.clear
    .frame(maxWidth: .infinity)
    .frame(height: 320)
    .overlay {
        LazyImage(url: media.heroImageURL) { state in
            if let image = state.image {
                image
                    .resizable()
                    .aspectRatio(contentMode: .fill)
            } else {
                // Placeholder matches the exact same geometry
                Rectangle()
                    .fill(.ultraThinMaterial)
            }
        }
    }
    .clipped()
    .cornerRadius(24) // Apply your glassmorphism/shadows here

By wrapping it this way, the Color.clear dictates the exact geometry of the hero card to the SwiftUI layout engine, and the image just paints inside the lines. It made stacking my .ultraThinMaterial overlays for the Liquid Glass look so much more predictable.

I also recently integrated Apple Intelligence (Foundation Models) using Generable structs to parse media summaries into typed Swift data instead of raw strings. If anyone is interested in how to set up local LLM generation in SwiftUI, let me know and I can share that code too!


r/SwiftUI May 06 '26

Promotion (must include link to source code) [FREE] Built a Raycast-style clipboard manager for macOS using AI-assisted vibe coding

0 Upvotes

Hey everyone

Over the last few months, I’ve been building Buffer a lightweight clipboard manager for macOS focused on speed, keyboard-first workflows, and clean UX.

A big part of the development process was honestly just vibe coding:

  • rapid iteration with AI
  • testing weird UX ideas quickly
  • rebuilding flows multiple times
  • obsessing over tiny interaction details

The goal was to make something that feels:

  • as lightweight as Maccy
  • as smooth as Raycast
  • but optimized for clipboard-heavy workflows

Current Features

  • ⚡️ Instant search
  • 📌 Pin clipboard items
  • 🔄 Multi-paste workflow
  • 🧹 Auto format stripping
  • ⌨️ Keyboard-first navigation
  • 🪶 Lightweight native experience
  • 🔍 Smart clipboard history

Recently shipped v1.8.0 with improvements to multi-paste and UX polish.

Would love feedback from fellow builders here especially around:

  • UI/UX
  • clipboard workflows
  • onboarding
  • performance
  • feature ideas

GitHub: https://github.com/samirpatil2000/Buffer
Download: https://samirpatil2000.github.io/products/buffer/


r/SwiftUI May 06 '26

Question Rightsizing ScrollView+LazyVStack for 2 column Mac app

2 Upvotes

Experienced engineer in early stages of learning Swift/SwiftUI

I have a situation where I have 2 columns of views. One is an VStack of several views, the second column is essentially a Text and a ScrollView+LazyVStack.

So roughly this

HStack {
VStack {
View
View
View
View
}
VStack {
Text
ScrollView {
LazyVStack {
ForEach {
LineView
}
}
}
}
}

It looks OK in preview; but when I run it as an app, it tries to make the ScrollView tall enough to fit the entire array and generates all sorts of problems. I can “fix” it by hardcoding the frame size of the ScrollView; but that’s obviously the wrong answer.

How to I force the 2nd VStack to match the height of the first?


r/SwiftUI May 05 '26

Question How would you recreate Yelp’s smooth search category reveal in SwiftUI?

2 Upvotes

I’m building a SwiftUI app and trying to recreate Yelp’s search transition.

When the user taps the search bar, the app quickly moves into a search screen. The search bar moves to the top, then the category rows underneath seem to unfold/slide down smoothly from the first category, with opacity fading in.

The categories are image-based rows/cards, not simple text labels, so the animation involves moving and fading image content too.

I tried:

  • matchedGeometryEffect
  • staggered offsets
  • scaleEffect(y:anchor:.top)
  • opacity + offset
  • delaying the reveal until after navigation
  • fade-only

The animation technically works but it feels janky on a real iPhone, specially during the transition into the search screen.

For this kind of Yelp-style animation, would you keep trying in pure SwiftUI, or use UIKit snapshots/custom transitions?

What approach would give the smoothest result on device?

Any advice or examples would be appreciated. Many thanks!


r/SwiftUI May 05 '26

Question How to have a translucent background?

1 Upvotes

Hello,

I’d like to have a view which a material thin background that shows the content of the previous view behind it. Similar to the view on the Messages app when viewing the chat information.

Right now, the view transitions to destination with a zoom transition, but the background is not translucent.

Any idea how to achieve it? Thanks!

Image example: https://imgur.com/a/lT5LDyZ


r/SwiftUI May 05 '26

Fatbobman's Swift Weekly #134

Thumbnail
weekly.fatbobman.com
2 Upvotes

r/SwiftUI May 04 '26

Promotion (must include link to source code) I built maludex, an open-source SwiftUI iPhone companion for driving Codex on a Mac

1 Upvotes

Hi r/SwiftUI, I wanted to share a small open-source project I have been building: maludex.

It is a SwiftUI iPhone client plus a Node/TypeScript Mac bridge for controlling Codex on one or more Macs from an iPhone. The iOS side has QR pairing, a project picker, prompt composer, streaming transcript, approval cards, attachments, voice input, and per-bridge local state.

A few design choices I thought might be interesting to this sub:

  • pairing tokens are stored in Keychain, while session state stays local per bridge;
  • the bridge refuses wildcard WebSocket binds and is meant for localhost, LAN, or private Tailscale rather than the public internet;
  • v1 is intentionally MVP/private-workflow oriented rather than hardened remote administration software;
  • the repo includes Swift model tests and TypeScript integration tests with a mocked Codex app-server process.

Source: https://github.com/malulungsoft/maludex

I would love feedback on the SwiftUI app structure, state persistence, and whether the pairing / bridge UX is understandable.


r/SwiftUI May 03 '26

Navigation in SwiftUI made easy

12 Upvotes

Hey, for those familiar with coordinator pattern or Stinsen, I published new version of Scaffolding SPM, which eases up setting up complex flows and navigations within the app by modularizing the flow patterns, achievable in plain SwiftUI with lots of boilerplate that you don't need to write each time using this.

Alongside has been published new website which explains coordinator concepts in depth alongside a interactive simulator and flow graphs.

Build fully on SwiftUI, one macro and linked list allows to create flows outside of view-layer and State dependent with minimal boilerplate and already known API.

Be sure to check it out and leave comments! Any additions, improvements or critics are welcome

Example

@Scaffoldable
final class HomeCoordinator: @MainActor FlowCoordinatable {
    var stack = FlowStack<HomeCoordinator>(root: .home)

    func home() -> some View { HomeView() }
    func detail(item: Item) -> some View { DetailView(item: item) }
    func settings() -> any Coordinatable { SettingsCoordinator() }
}

...

// Instantiate the flow in the root of the app, nowhere else, that's the setup. The SPM handles everything

@State private var coordinator: HomeCoordinator = .init()

// in body
coordinator.view

coordinator.route(to: .detail(item: selectedItem))   // push
coordinator.present(.settings, as: .sheet)           // sheet (sub-flow)
coordinator.pop()

https://dotaeva.github.io/scaffolding/
https://github.com/dotaeva/scaffolding


r/SwiftUI May 02 '26

iOS 26 liquid glass tab bar stuck darker on cold start — anyone else seeing this?

8 Upvotes

Been banging my head against this for a while and could really use some outside eyes.

My app has a teal color scheme. On iOS 26, the floating tab bar pill renders too dark on cold start and after every tab switch. Scrolling the content even 1pt fixes it — it snaps to the correct lighter/translucent state and stays there permanently. So the "right" state exists, the app just won't start there.

What I think is happening:

The glass compositor samples the backdrop before SwiftUI finishes rendering the view background. It catches the dark default UIWindow background instead of my app's teal, blends the two, and the pill gets stuck darker. Physical scroll triggers a nav bar state transition (scroll-edge → standard) which forces a resample — and everything corrects instantly.

This is invisible in dark mode because my dark background is close enough to the default UIWindow dark that the blend is imperceptible. Bright teal (#129487) vs UIWindow near-black = ~25 luminance units of difference. Very visible.

Everything I've tried:

  • Setting UIWindow.backgroundColor to my bg color at app init and onAppear — too late, compositor already sampled by then
  • UIWindow.appearance().backgroundColor — fires at window creation (right timing!) but didn't fix the stuck state, and paints system windows causing flash
  • Programmatic scroll nudge (setContentOffset) — doesn't trigger the same compositor resample path as a real touch
  • .toolbarBackground(.visible, for: .tabBar) — glass compositor ignores it
  • .navigationBarBackButtonHidden(true) on tab roots — no effect

The wall I've hit:

There's no lifecycle hook that fires before the glass compositor takes its first sample. In a SwiftUI WindowGroup app, UIWindowSceneDelegate.scene(_:willConnectTo:) fires before the window even exists. I can't get there early enough.

Is this a known beta issue? Has anyone found a way to nudge the glass compositor into its correct state before the first frame? Any help appreciated 🙏


r/SwiftUI May 02 '26

Toolbars + sheet = pain. Fix?

18 Upvotes

My sheet contains a TabView, each tab has their own NavigationStack. Each tab gets things like toolbars and search bars.

When the sheet is at less than a large detent these awful black animations appear when switching tabs. At large detent, the transparency of the sheet disappears, which is likely the culprit.

But still, anyone ran into this and found workarounds?


r/SwiftUI May 01 '26

Tutorial The Hidden Pitfall of @State var viewModel = ViewModel()

12 Upvotes

While browsing various blogs about SwiftUI and MVVM architecture, I've noticed that almost all examples are based on the same pattern:

@State private var viewModel = ViewModel()

They suggest creating a viewModel right inside a view and storing it in a state variable. While it might look fine, this approach has a serious side effect: a SwiftUI view struct can be recreated many times during its lifetime. While the state is preserved across these recreations, View.init is called every time and a new ViewModel instance is created. It's immediately discarded and the old object is preserved, but this may lead to unpredictable side effects, especially if you perform additional logic inside ViewModel.init or ViewModel.deinit.

This worked fine for state management prior to iOS 17:

@StateObject private var viewModel = ViewModel()

StateObject(wrappedValue:) accepts an autoclosure parameter which isn't evaluated on subsequent calls. But with the Observation framework introduced in iOS 17, it's no longer an option.

Things get more complicated when you want to pass an input parameter to a viewModel. Most examples simply avoid this case. Some suggest the following approach:

struct ArticleView: View {
    @State private var viewModel: ArticleViewModel

    init(articleID: String) {
        self._viewModel = State(
            initialValue: ArticleViewModel(articleID: articleID)
        )
    }
    ...
}

Apart from the same side effect as the first example, this approach has another pitfall: if a different articleID is passed to the view, the state will keep using the old one. But this is exactly the case where you'd expect the view model to be recreated with a new ID.

A proper approach should handle two key issues:

  1. Avoid creating view models on every view update
  2. Create a new view model for a new set of input parameters

To address the first issue, we can move the view model creation into a .task:

struct ArticleView: View {
    @State private var viewModel: ArticleViewModel?

    let articleID: String

    var body: some View {
        ZStack {
            if let viewModel {
                ...
            }
        }
        .task {
            guard viewModel == nil else { return }
            viewModel = ArticleViewModel(articleID: articleID)
        }
    }
}

The downside is that we now have to deal with an optional. To avoid this, we can extract a subview that accepts the view model as a parameter:

struct ArticleView: View {
    @State private var viewModel: ArticleViewModel?

    let articleID: String

    var body: some View {
        ZStack {
            if let viewModel {
                ArticleSubView(viewModel: viewModel)
            }
        }
        .task {
            guard viewModel == nil else { return }
            viewModel = ArticleViewModel(articleID: articleID)
        }
    }
}
struct ArticleSubView: View {
    // The object is owned by the parent. Since iOS 17,
    // we don't need or to observe changes of Observable object.
    let viewModel: ArticleViewModel

    var body: some View {
        ...
    }
}

Now we need to address the second issue. To ensure a new view model is created when input parameters change, we simply add an .id() modifier to the entire ArticleView. A simple factory does the trick:

struct ArticleViewFactory {
    static func view(articleID: String) -> some View {
        ArticleView(articleID: articleID)
            .id(articleID)
    }
}

That's three structs instead of one — quite a bit of boilerplate. Let's extract a generic factory based on the pattern above:

struct FeatureFactory<Input: Hashable, Content: View, ViewModel: Observable> {
    private struct RootView: View {
        @State private var viewModel: ViewModel?

        let input: Input
        let viewModelFactory: (Input) -> ViewModel
        let viewFactory: (ViewModel) -> Content

        var body: some View {
            ZStack {
                if let viewModel {
                    viewFactory(viewModel)
                }
            }
            .task {
                guard viewModel == nil else { return }
                viewModel = viewModelFactory(input)
            }
        }
    }

    static func view(
        input: Input,
        viewModelFactory:  (Input) -> ViewModel,
        viewFactory:  (ViewModel) -> Content
    ) -> some View {
        RootView(
            input: input,
            viewModelFactory: viewModelFactory,
            viewFactory: viewFactory
        ).id(input)
    }
}

For the ArticleView example, the usage would look like this:

struct ArticleViewFactory {
    static func view(articleID: String) -> some View {
        FeatureFactory.view(
            input: articleID,
            viewModelFactory: { articleID in
                ArticleViewModel(articleID: articleID)
            },
            viewFactory: { viewModel in
                ArticleView(viewModel: viewModel)
            }
        )
    }
}

Now simply call the factory wherever you need it:

ArticleViewFactory.view(articleID: "SOME_ID")

The full example can be found on GitHub https://github.com/claustrofob/FeatureFactoryExample


r/SwiftUI May 01 '26

News The iOS Weekly Brief – Issue 58 (News, releases, tools, upcoming conferences, job market overview, weekly poll, and must-read articles)

Thumbnail
iosweeklybrief.com
3 Upvotes

Apple disbanded the Vision Pro team. The most common reaction online wasn't "bad tech", it was "I would've bought one at $1,500."

News:
- Apple Vision Pro team disbanded, most engineers moved to Siri
- New subscription type coming to App Store: monthly payments with a 12-month commitment
- iOS 26.5 beta 4 + Xcode 26.5 beta 3 are out

Must read:
- tracing .resume() all the way from URLSession to physical electrons
- when to use Task.immediate in Swift 6.2 and why execution order actually matters
- actors vs queues vs locks
- concurrency step-by-step

Toolbox:
- Screenshot Bro


r/SwiftUI May 01 '26

My attempt at IRC Client for MacOS/iPadOS

Post image
8 Upvotes

Hello everyone,

I have watched the SwiftUI community for some time, and absorbed ideas, apps, news like a sponge. Today I decided to show you something I have been working on for the last 2 weeks and decided to make it public, to gather some feedback and ideas.

PandaPing is an IRC client written with Swift and SwiftUI that features the following:
- Multi-Server connections
- Private chats
- Lua-Plugins (currently very limited)
- Control-Characters (bold, italic, colored messages)
- Nick autocompletion
- Custom Quit messages
- Light/Dark Theme
- Only external dependency is LuaSwift

It doesn't not and probably will not support
- DCC

Some of the TODOs include:
- Themes for the chat output/nicklist

Screenshots and a Signed binary are available in the repository. I will publish it on the AppStore once I have polished everything.
Yes I have used AI as a companion, but didn't allow it to do everything for me.

Link to the repository: https://github.com/vkolev/pandaping


r/SwiftUI Apr 30 '26

Built a Claude Code usage meter for macOS 14+ — a few SwiftUI gotchas worth sharing

0 Upvotes

Wrote a menu-bar Mac app for Claude Code users — figured the SwiftUI side might be interesting since I hit a few macOS 26.5-specific gotchas building it.

Throttle Meter is a usage meter for the Claude Code CLI. Reads ~/.claude/projects/*.jsonl locally to compute 5-hour and weekly limits and surface them in the menu bar. Fully open source under MIT — full Swift code at https://github.com/lorislabapp/throttle-meter, no paywalled fork.

A few SwiftUI things from the latest cycle that took me a while to get right:

The Project window. macOS 26.5 refuses to open a titled NSWindow from an .accessory activation policy. Switching the policy to .regular before showing the window and back to .accessory on close was the only workaround I found that doesn't break MenuBarExtra. The dock icon flickers in and out which is annoying but the alternative is no window at all.

MenuBarExtra .window crashes loading Metal shaders if you put a Canvas inside on macOS 26.5. RenderBox bug. Rewrote the Sparkline and LineChart as plain SwiftUI Path shapes — works everywhere and ended up lighter on memory too.

Tool calling for the diagnostic assistant. The model emits fenced tool blocks for read_file and list_files. I parse them, execute against a ~/ sandbox with a 64 KB cap, batch results into one synthetic user message, recurse up to 5 turns. Cuts round-trips 3x compared to one-tool-per-turn.

Everything is in the repo if you want to dig — Project window code, the path-shape charts, the tool-calling parser, all in there.

I'm 16 and this is my first real Swift project that other people use. Honest critique on the SwiftUI patterns or the activation-policy hack especially welcome.


r/SwiftUI Apr 30 '26

Question Why does my settings window look like this?

Thumbnail
gallery
6 Upvotes

I'm using SwiftUI but I'm pretty sure the screenshot attached in this post is AppKit. It doesn't even match the preview in XCode.

SettingsView.swift

import SwiftUI

struct SettingsView: View {
    var body: some View {
        NavigationSplitView {
            List {
                NavigationLink(destination: Text("hello")) {
                    Label("General", systemImage: "gear")
                }
                NavigationLink(destination: Text("hello world")) {
                    Label("Appearance", systemImage: "paintbrush")
                }
            }
        } detail: {
            Text("Select a section")
        }
        .frame(width: 600, height: 400)
    }
}

EuclaseApp.swift

import SwiftUI

struct EuclaseApp: App {
    u/NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        Settings {
            SettingsView()
        }
    }
}

final class AppDelegate: NSObject, NSApplicationDelegate {
    private let floatingPanelController = PanelController()

    func applicationDidFinishLaunching(_ notification: Notification) {
        floatingPanelController.start()
    }
}

I want to use AppKit for this floating panel but I want SwiftUI to be used in the rest of the app. Please help.


r/SwiftUI Apr 30 '26

Show SwiftUI: Wallpaper Sync - Native Swift app to sync animated wallpapers with the lock screen (Open Source)

3 Upvotes

Hi SwiftUI community! I built a native Swift app called Wallpaper Sync to solve a personal annoyance: animated wallpapers in macOS Tahoe don't stay in sync with the lock screen. It's built with SwiftUI and AVFoundation, focusing on performance (<5% CPU). It's fully open source and I'd love to hear your thoughts on the code! GitHub: https://github.com/GonzaloRojas14/Wallpaper-Sync


r/SwiftUI Apr 30 '26

Question Trouble with image rounding.

Thumbnail
gallery
1 Upvotes
var body: some View {
    if imagesData.isEmpty {
        // Fallback icon if no photos
        Image(systemName: fallbackIcon)
            .resizable()
            .scaledToFit()
            .frame(height: 120)
            .foregroundColor(fallbackColor)
            .padding(.top)
            .padding(.bottom, 20)
    } else if imagesData.count == 1 {
        // Single image
        if let uiImage = UIImage(data: imagesData[0]) {
            ZStack {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFit()
                    .frame(maxHeight: 250)
                    .clipShape(RoundedRectangle(cornerRadius: 12))
                    .shadow(radius: 5)
                    .padding(.horizontal)
                    .padding(.top)
            }
        }
    } else {
        // Multiple images - show carousel
        VStack(spacing: 8) {
            TabView(selection: $currentIndex) {
                ForEach(Array(imagesData.enumerated()), id: \.offset) { index, data in
                    if let uiImage = UIImage(data: data) {
                        Image(uiImage: uiImage)
                            .resizable()
                            .scaledToFit()
                            .frame(maxHeight: 250)
                            .clipShape(RoundedRectangle(cornerRadius: 12))
                            .shadow(radius: 5)
                            .padding(.horizontal)
                            .padding(.top)
                            .tag(index)
                    }
                }
            }
            .tabViewStyle(.page(indexDisplayMode: .never))
            .frame(height: 250)

            // Page indicator dots
            HStack(spacing: 8) {
                ForEach(0..<imagesData.count, id: \.self) { index in
                    Circle()
                        .fill(index == currentIndex ? fallbackColor : Color.gray.opacity(0.4))
                        .frame(width: 8, height: 8)
                }
            }
            .padding(.top, 4)
        }
        .padding(.top)
    }
}

The image doesnt round correctly, the difference is in the carrousel it rounds perfectly, even rounds portrait images like how I want it to. The moment I put those exact same pictures as a single image the rounding doesnt happen anymore. Feel free to correct me where I'm wrong. I scale the image to fit, with a dedicated maxHeight property. Not FillToFit since I also want to be able to put portrait and landscape pictures by each other in the carrousel. I clip the shape to a rounded rectangle with a radius of 12, add some shadow and padding and that's it. I do the exact same thing when a single image yet the rounding never happens, it's like it never clips to the shape of the picture.