Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Created

The banner cannot be displayed correctly using 'LiveCommunicationKit'.
Since Callkit is not supported in mainland China, 'LiveCommunicationKit' is currently being used. When a VoIP push notification is received, the banner does not display correctly, but the phone icon in the top left corner, the ringtone, and vibration are present. I followed the solution in "https://developer.apple.com/forums/thread/774958?answerId=827083022#827083022" to resolve the crash issue, but the banner is still not displayed.
Topic: UI Frameworks SubTopic: General
0
0
55
3w
Changing the menu bar display name
Hello, I'm currently working on an app that will have a different name (and UI) depending on an environment variable that is set by that app's custom installer that I also wrote. I'm trying to change the app name that is displayed in the menu bar (top left) programmatically. I've done some research and found that it's probably not possible to do so because it's fetched from the app's Info.plist The answer is probably already there but I'll ask the question: Is it possible to change the app's name in the menu bar without tampering with the Info.plist (as it will break the signature at runtime, and it can't be done at compile time) The use case here is that I'm shipping a single app with multiple installers, because the app will be the same for all sets of users but it will have minor UI changes (which in my opinion, don't need an entire separate release), the installers will set a flag that the app will, based on, change its UI to the corresponding set of users. For the most part it's been successful but only small issue remain like this one. The reason it's done like that is when updating I'll ship 1 release for all users to update rather than having to ship multiple releases with no difference between them
1
0
104
3w
CarPlay CPGridTemplate corrupt items
For some reason, Carplay 18.x works fine, however in under certain situations in our app, Carplay 26.x breaks. The expected grid layout should be : However, this is what we see in some cases when we update our templates. I have not been able to isolate the cause of this issue. Has anyone ever seen this happen on their CarPlay apps and discovered the cause? The data sets fed into the templates are identical, the difference is in some of the timing and update order...
0
0
86
3w
WebAuthenticationSession doesn't seem to do anything on macOS
I'm attempting to use WebAuthenticationSession from Authentication Services (https://developer.apple.com/documentation/authenticationservices/webauthenticationsession) in a SwiftUI app on macOS. According to the docs, it is supported since macOS 13.3 and I'm testing on 26. I'm deploying the same code to iOS as well, and it works there in a simulator, but I sometimes have to tap the button that triggers the authenticate(…) call more than once. I've attached a simplified and redacted version of the code below. It works on iOS, but on macOS the authenticate call never returns. There seems to be very little documentation and discussion about this API and I'm running out of ideas for getting this to work. Is this just a bug that Apple hasn't noticed? import SwiftUI import AuthenticationServices import Combine struct PreAuthView: View { @Binding var appState: AppState @Binding var credentials: Credentials? @Environment(\.webAuthenticationSession) private var webAuthenticationSession @State private var plist: String = "" func authenticate() async { guard var authUrl = URL(string: "REDACTED") else { return } guard var tokenUrl = URL(string: "REDACTED") else { return } let redirectUri = "REDACTED" let clientId = "REDACTED" let verifier = "REDACTED" let challenge = "REDACTED" authUrl.append(queryItems: [ .init(name: "response_type", value: "code"), .init(name: "client_id", value: clientId), .init(name: "redirect_uri", value: redirectUri), .init(name: "state", value: ""), .init(name: "code_challenge", value: challenge), .init(name: "code_challenge_method", value: "S256"), ]) let scheme = "wonderswitcher" do { print("Authenticating") let redirectUrl = try await webAuthenticationSession.authenticate( using: authUrl, callback: .https(host: "REDACTED", path: "REDACTED"), additionalHeaderFields: [:], ) print("Authenticated?") print(redirectUrl) let queryItems = URLComponents(string: redirectUrl.absoluteString)?.queryItems ?? [] let code = queryItems.filter({$0.name == "code"}).first?.value let session = URLSession(configuration: .ephemeral) tokenUrl.append(queryItems: [ .init(name: "grant_type", value: "authorization_code"), .init(name: "code", value: code), .init(name: "redirect_uri", value: redirectUri), .init(name: "code_verifier", value: verifier), .init(name: "client_id", value: clientId), ]) var request = URLRequest(url: tokenUrl) request.httpMethod = "POST" let response = try await session.data(for: request) print(response) } catch { return } } var body: some View { NavigationStack { VStack(alignment: .leading, spacing: 12) { Text("This is the pre-auth view.") HStack { Button("Log in") { Task { await authenticate() } } Spacer() } Spacer(minLength: 0) } .padding() .navigationTitle("Pre-Auth") } } } #Preview { PreAuthView(appState: .constant(.preAuth), credentials: .constant(nil)) }
Topic: UI Frameworks SubTopic: SwiftUI
3
0
66
3w
UIWindowScene sizeRestrictions minimumSize not working on iPadOS
Hello, following Apple docs and guidance from WWDC I'm trying to set a minimum size for my scene, for example I want it to minimally be 3/4 the width and height of the device. I've removed the UIRequiresFullScreen Info.plist property. The app does run in windowed mode and does have a resizing handle. I've implemented this UISceneDelegate: var window: UIWindow? var cameraWindow: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window = UIWindow(windowScene: scene as! UIWindowScene) // setup root view controller let rootViewController: MainViewController = MainViewController(nibName: "Main", bundle: nil) let navController: NavigationController = NavigationController(rootViewController: rootViewController) navController.modalPresentationStyle = .fullScreen // set reasonable minimum sizes for WindowScene if let windowScene: UIWindowScene = scene as? UIWindowScene { if #available(iOS 16.0, *) { let windowSize: CGSize = windowScene.coordinateSpace.bounds.size windowScene.sizeRestrictions?.minimumSize.width = windowSize.width * 0.75 windowScene.sizeRestrictions?.minimumSize.height = windowSize.height * 0.75 } } window?.rootViewController = navController window?.makeKeyAndVisible() } } And proven via debugger that this code is being executed. I have the following observations: After setting these minimumSize properties I see the width and height both contain 0 afterwards, as if the property settings are discarding the value. I've even used hard-coded values instead of reading the coordinateSpace.bounds, to no avail. The scene is allowing resizing well below these minimums, about 1/3 the width and 1/2 the height. Anyone else observed this and have suggestions?
Topic: UI Frameworks SubTopic: UIKit
0
0
64
3w
SwiftUI iOS 26 .safeAreaBar issue with large navigation title
I have some really straight forward code in a sample project. For some reason when the app launches the title is blurred obscured by scrolledgeeffect blur. If I scroll down the title goes small as it should do and all looks fine. If I scroll back to the top, just before it reaches the top the title goes large and it looks correct, but once it actually reaches/snaps to the top, is then incorrectly blurs again. Is there anything obvious I'm doing wrong? Is this a bug? struct ContentView: View { var body: some View { NavigationStack { ScrollView { VStack { Rectangle().fill(Color.red.opacity(0.2)).frame(height: 200) Rectangle().frame(height: 200) Rectangle().frame(height: 200) Rectangle().frame(height: 200) Rectangle().frame(height: 200) } } .safeAreaBar(edge: .top) { Text("Test") } .navigationTitle(Title") } } }
4
1
418
3w
Change tint of back button in UINavigationItem on iOS 26
I am struggling to change the tint of the back button in an UINavigationItem. In iOS 18.6 it looks like this while on iOS 26 the same looks like this I can live without the Dictionary but I'd like to get the blue color back. In viewDidLoad() I have tried navigationItem.backBarButtonItem?.tintColor = .link but this did not work since navigationItem.backBarButtonItem is nil. My second attempt was navigationController?.navigationBar.tintColor = .link but this didn't work either. I have even set the Global Tint to Link Color but this had no effect either. Does anyone have an idea how to change the tint of the back button in an UINavigationItem on iOS 26?
Topic: UI Frameworks SubTopic: UIKit Tags:
6
1
355
3w
Changing Dock Icon for my Qt app
Hello, I'm trying to make a white-Label sort of thing for my app, that is: a script runs before the app launches, sets a certain LaunchAgent command that sets and environment variable, and based on that variable's value tha main app's icon changes to a certain logo (change only happens in the dock because changing the icon on disk breaks the signature) When the app launches it takes a noticeable time until the dock icon changes to what I want, so I worked around that by setting the app's plist property to hide the dock icon and then when the app is launched I call an objc++ function to display the icon in the dock again (this time it displays as the new icon) The showing happens through [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; The problem happens when I try to close the app, it returns back to the old logo before closing which is what I want to prevent. I tried hiding the app dock icon before closing but even the hiding itself changes the icon before hiding The hiding happens through [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited]; My goal is that the main app icon doesn't appear to the user through the dock, and that the icon that is only visible is the other one that changes during runtime The reason for this is that I have an app that should be visible differently depending on an environment variable that I set using an installer app. The app is the same for all users with very minor UI adjustments depending on that env variable's value. So instead of creating different versions of the app I'd like to have just 1 version that adjusts differently depending on the env variable's value. Somehow this is the only step left to have a smooth experience Feel free to ask more clarification questions I'd be happy to help Thank you
5
0
385
3w
https://stackoverflow.com/questions/79865253/watchos-swiftui-ui-redraws-are-delayed-in-always-on-power-saving-mode-despite
I'm working on a watchOS app using SwiftUI that updates its UI based on regular, time-driven logic. On a real Apple Watch, after the app has been running for ~1 minute, the device enters Always-On / power-saving display mode (screen dimmed, wrist down). From that point on, SwiftUI UI updates become noticeably delayed. The underlying logic continues to run correctly, but the UI only redraws sporadically and often "catches up" once the screen becomes fully active again. The app is running in workout mode, which keeps it alive and maintains WatchConnectivity, but this does not prevent UI redraw throttling. Below is a minimal reproducible example that demonstrates the issue. PlaybackModel.swift import SwiftUI @MainActor final class PlaybackModel: ObservableObject { @Published var beat: Int = 0 private var timer: Timer? func start() { timer?.invalidate() timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in Task { @MainActor in self.beat += 1 } } } func stop() { timer?.invalidate() } } ContentView.swift (watchOS) import SwiftUI struct ContentView: View { @StateObject private var model = PlaybackModel() var body: some View { VStack { Text("Beat: \(model.beat)") .font(.largeTitle) } .onAppear { model.start() } .onDisappear { model.stop() } } } Observed Behavior • The beat value continues to increase reliably. • After the watch enters Always-On / power-saving mode, SwiftUI redraws are delayed or skipped. • When the screen becomes fully active again, the UI catches up. Questions: • Is this UI redraw throttling in Always-On / power-saving mode an unavoidable system limitation on watchOS? • Is there any supported way to keep consistent SwiftUI update frequency while the app is visible but dimmed?
1
0
90
3w
[SwiftUI][DragDrop][iPadOS] Drop into TabView Sidebar Tab not triggering. How to debug?
Are there tools to inspect why a drag-and-drop drop is not triggering in a SwiftUI app? I've declared .draggable on the dragging view, and .dropDestination on the receiving TabContent Tab view. This combination of modifiers is working on a smaller demo app that I have, but not on my more complex one. Is there a means to debug this in SwiftUI? I'd like to see if the drag-and-drop pasteboard actually has what I think it should have on it. Notably: "TabContent" has a far more restricted list of modifiers that can be used on it.
0
0
85
3w
Persisting User Settings with SwiftData
I was wondering what the recommended way is to persist user settings with SwiftData? It seems the SwiftData API is focused around querying for multiple objects, but what if you just want one UserSettings object that is persisted across devices say for example to store the user's age or sorting preferences. Do we just create one object and then query for it or is there a better way of doing this? Right now I am just creating: import SwiftData @Model final class UserSettings { var age: Int = 0 var sortAtoZ: Bool = true init(age: Int = 0, sortAtoZ: Bool = true) { self.age = age self.sortAtoZ = sortAtoZ } } In my view I am doing as follows: import SwiftUI import SwiftData struct SettingsView: View { @Environment(\.modelContext) var context @Query var settings: [UserSettings] var body: some View { ForEach(settings) { setting in let bSetting = Bindable(setting) Toggle("Sort A-Z", isOn: bSetting.sortAtoZ) TextField("Age", value: bSetting.age, format: .number) } .onAppear { if settings.isEmpty { context.insert(UserSettings(age: 0, sortAtoZ: true)) } } } } Unfortunately, there are two issues with this approach: I am having to fetch multiple items when I only ever want one. Sometimes when running on a new device it will create a second UserSettings while it is waiting for the original one to sync from CloudKit. AppStorage is not an option here as I am looking to persist for the user across devices and use CloudKit syncing.
3
0
326
3w
hapticpatternlibrary.plist error with Text entry fields in Simulator only
When I have a TextField or TextEditor, tapping into it produces these two console entries about 18 times each: CHHapticPattern.mm:487 +[CHHapticPattern patternForKey:error:]: Failed to read pattern library data: Error Domain=NSCocoaErrorDomain Code=260 "The file “hapticpatternlibrary.plist” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Library/Audio/Tunings/Generic/Haptics/Library/hapticpatternlibrary.plist, NSURL=file:///Library/Audio/Tunings/Generic/Haptics/Library/hapticpatternlibrary.plist, NSUnderlyingError=0x600000ca1b30 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} <_UIKBFeedbackGenerator: 0x600003505290>: Error creating CHHapticPattern: Error Domain=NSCocoaErrorDomain Code=260 "The file “hapticpatternlibrary.plist” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Library/Audio/Tunings/Generic/Haptics/Library/hapticpatternlibrary.plist, NSURL=file:///Library/Audio/Tunings/Generic/Haptics/Library/hapticpatternlibrary.plist, NSUnderlyingError=0x600000ca1b30 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} My app does not use haptics. This doesn't appear to cause any issues, although entering text can feel a bit sluggish (even on device), but I am unable to determine relatedness. None-the-less, it definitely is a lot of log noise. Code to reproduce in simulator (xcode 26.2; ios 26 or 18, with iPhone 16 Pro or iPhone 17 Pro): import SwiftUI struct ContentView: View { @State private var textEntered: String = "" @State private var textEntered2: String = "" @State private var textEntered3: String = "" var body: some View { VStack { Spacer() TextField("Tap Here", text: $textEntered) TextField("Tap Here Too", text: $textEntered2) TextEditor(text: $textEntered3) .overlay(RoundedRectangle(cornerRadius: 8).strokeBorder(.primary, lineWidth: 1)) .frame(height: 100) Spacer() } } } #Preview { ContentView() } Tapping back and forth in these fields generates the errors each time. Thanks, Steve
2
0
273
3w
Choppy minimized search bar animation
The new .searchToolbarBehavior(.minimized) modifier leads to a choppy animation both on device and SwiftUI canvas (iOS 26.2): I assume this is not the intended behaviour (reported under FB21572657), but since I almost never receive any feedback to my reports, I wanted to see also here, whether you experience the same, or perhaps I use the modifier incorrectly? struct SwiftUIView: View { @State var isSearchPresented: Bool = false @State var searchQuery: String = "" var body: some View { TabView { Tab { NavigationStack { ScrollView { Text(isSearchPresented.description) } .navigationTitle("Test") } .searchable(text: $searchQuery, isPresented: $isSearchPresented) .searchToolbarBehavior(.minimize) // **Choppy animation comes from here?** } label: { Label("Test", systemImage: "calendar") } Tab { Text("123") } label: { Label("123", systemImage: "globe") } } } } #Preview { if #available(iOS 26, *) { SwiftUIView() } else { // Fallback on earlier versions } }
4
0
328
3w
UI Tests troubles with Xcode 26.1 and Xcode 26.2
Since I moved to Xcode 26.1 and Xcode 26.2 then, my UI tests all fail only for iOS 26+, for both simulator and real device. Everything worked perfectly with Xcode 26.0, and the code base of the application under test and the test cases are the same. With Xcode 26.0, the tests pass for iOS 26+ and iOS < 26, for both simulator and real device. In addition, even the Accessibility Inspector tool fails to display the view hierarchy for iOS 26+ with Xcode 26.2. With Xcode 26.0, whatever are the devices and the OS versions, the tool was able to display the view hierarchy. Otherwise the tool is empty even if the device and app are selected. This failing tests issue occurs both on my local environment and on GitHub Actions runners, excluding the hypothesis I have troubles with my own side. The error message for failing tests explains the element cannot be found anymore. Given for example the test case: @MainActor func testMakeScreenshotsForDocumentation_Button() { let app = launchApp() goToComponentsSheet(app) waitForButtonToAppear(withWording: "app_components_button_label", app) tapButton(withWording: "app_components_button_label", app) tapButton(withWording: "Strong", app) takeScreenshot(named: "component_button_", ACDC.buttonX, ACDC.buttonY, ACDC.buttonWidth, ACDC.buttonHeight, app) } the goToComponentSheet(app) line shows the error: ActionsDocumentationScreenshots.testMakeScreenshotsForDocumentation_Button() In details the function: /// Opens the page of the components, i.e. tap on the 2nd of the tab bar @MainActor func goToComponentsSheet(_ app: XCUIApplication) { app.tabBars.buttons.element(boundBy: 1).tap() } with the following error on the app.tabBars line: .../AppTestCase.swift:157 testMakeScreenshotsForDocumentation_Button(): Failed to tap Button (Element at index 1): No matches found for Descendants matching type TabBar from input {(Application, pid: 1883)} I have the feeling with Xcode 26.2 (and Xcode 26.1) the view hierarchy is not accessible anymore for both XCUITest framework and Accessibility Inspector tool. Note I have on my side macOS Tahoe 26.1 (25B78) and my GitHub Actions runner are on macOS 26.0.1 (25A362). When I used Xcode 26.0 I was on macOS Tahoe 26.1 (25B78) . Any ideas? 🙂
2
0
250
3w
"canOpenURL:" on a thread that isn`t main thread?
When I call this method on a thread that isn`t thread. And chose main thread check on target, The Console show the world : Main Thread Checker: UI API called on a background thread: -[UIApplication canOpenURL:] PID: 8818, TID: 10191278, Thread name: (none), Queue name: com.myqueue.canopen, QoS: 0 Backtrace: 4 TestDemo 0x0000000102f6c068 __39-[AppTools isExists:]_block_invoke_3 + 892 5 CoreFoundation 0x000000019e22995c 7519E999-1053-3367-B9D5-8844F6D3BDC6 + 1042780 6 CoreFoundation 0x000000019e12ec98 7519E999-1053-3367-B9D5-8844F6D3BDC6 + 15512 7 TestDemo 0x0000000102f6bba0 __39-[AppTools isExists:]_block_invoke_2 + 424 8 libdispatch.dylib 0x0000000103a4d7fc _dispatch_call_block_and_release + 24 9 libdispatch.dylib 0x0000000103a4ebd8 _dispatch_client_callout + 16 10 libdispatch.dylib 0x0000000103a55b48 _dispatch_lane_serial_drain + 744 11 libdispatch.dylib 0x0000000103a566e4 _dispatch_lane_invoke + 448 12 libdispatch.dylib 0x0000000103a61adc _dispatch_workloop_worker_thread + 1324 13 libsystem_pthread.dylib 0x000000019df72b88 _pthread_wqthread + 276 14 libsystem_pthread.dylib 0x000000019df75760 start_wqthread + 8
1
0
118
3w
iPadOS 26.3 Beta 1 RequiresFullScreen Deprecation
Hello everyone, I have an app that is used in the education sector for high stakes assessment testing. I reviewed a lot of the WWDC2025 information in June, however, it seems we missed something critical in the What's new in UIKIt presentation. That would be the deprecation of UIRequiresFullScreen. We currently use this in our app and have been using it since iOS/iPad OS 9 when our app was written. The deprecation of this property has caused some major issues in our layout. Keep in mind we are a hybrid app so our mobile app is self-hosting a fullscreen version of WKWebView under the hood. This is common across assessment developers in the education sector. I removed the property and went through the migration guide (https://developer.apple.com/documentation/technotes/tn3192-migrating-your-app-from-the-deprecated-uirequiresfullscreen-key) and it doesn't appear to be straight forward on how to lock the orientation in landscape. I tried several different approaches: Requesting the screen orientation lock we had issues where if a user launched it in portrait it would be locked to portrait but we would want to update the display to shift it to landscape as a business requirement supporting both landscape right and landscape left. We also tried overriding the method supportedInterfaceOrientations and utilizing the .landscape enum with no success. It fires just fine but nothing takes effect. Backwards compatibility support there is no guidance on backwards compatibility support and Xcode wants us to do an availability check when using some of the new methods for updating geometry. What is the guidance in this case because we support back to iPadOS 16.0 as a business requirement. Can anyone give us some insight as we are current trying to get ahead of this while 26.3 is still in beta as this would affect our customers deeply because of the UI jank we get as a result of this deprecation.
1
0
174
3w
UIButtonConfiguration and button disabled state
I am trying to use the UIButtonConfiguration to set the UI state for the button.isEnabled status. I do see the ConfigurationUpdateHandler code below being executed but when the button.isEnabled is set to false, the UI does not reflect the updated backgroundColor. Instead it is a very light gray but the foregroundColor/text is being updated. It seems that the default disabled button treatment is being used despite being set to a different color. Is there a better way to suppress the default UIButton disabled state so I can customize? [newButton setConfigurationUpdateHandler:^(__kindof UIButton * _Nonnull button) { UIButtonConfiguration *updatedConfiguration; if (newButton.configuration != nil) { updatedConfiguration = newButton.configuration; if (button.isEnabled) { updatedConfiguration.baseBackgroundColor = [UIColor darkGrayColor]; updatedConfiguration.baseForegroundColor = [UIColor whiteColor]; } else { updatedConfiguration.baseBackgroundColor = [UIColor greenColor]; updatedConfiguration.baseForegroundColor = [UIColor blackColor]; } } button.configuration = updatedConfiguration; }];
Topic: UI Frameworks SubTopic: UIKit
1
0
138
3w
Tahoe sidebar - icon sizing is wrong
Hi there. I am trying to figure out how to make a macOS Tahoe app in SwiftUI with a sidebar. The problem I’m having is that the icons are the wrong size. If you visually compare the resulting sidebar with any built-in macOS app (Finder, Notes, Mail, Music, etc.) the built-in apps all have larger icons and the spacing is different from my SwiftUI app, which has too small icons and (I think) wrong spacing. I am trying to figure out what SwiftUI code I need to write to get a sidebar that looks the same as the other built-in macOS Tahoe apps. It’s also important to note that Tahoe sidebars have larger icons at the top level, and in cases where the items have a disclosure triangle with additional items nested within, the nested icons have smaller icons. I have not figured out how to properly replicate this effect either. I have spent quite a lot of time on trial-and-error with various combinations of .frame() and .font() modifiers. However, none of the results look quite right to me, and besides that, I think it is fundamentally the wrong approach; the UI or OS should be handling the sizing and spacing automatically, I shouldn’t have to specify it manually, as this is likely to break in past and future OS versions (and it never really looks exactly right in the first place). I am hoping there is some missing modifier that I am unaware of, which would solve this; or perhaps, some fundamental aspect of making lists in sidebars that I have missed. I would very much appreciate any advice. If you drop my code below into a new Xcode project, and compare it to a Finder window, you should be able to easily see the problem. import SwiftUI struct ContentView: View { var body: some View { splitView } @ViewBuilder var splitView: some View { NavigationSplitView { sidebar } detail: { helloWorld } } @ViewBuilder var sidebar: some View { List { NavigationLink { helloWorld } label: { Label("Test", systemImage: "book") } NavigationLink { helloWorld } label: { Label("Test 2", systemImage: "folder") } NavigationLink { helloWorld } label: { Label("Test 3", systemImage: "house") } DisclosureGroup( content: { NavigationLink { helloWorld } label: { Label("Test", systemImage: "book") } NavigationLink { helloWorld } label: { Label("Test 2", systemImage: "folder") } NavigationLink { helloWorld } label: { Label("Test 3", systemImage: "house") } }, label: { Label("Test 4", systemImage: "document") } ) } } @ViewBuilder var helloWorld: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() } } #Preview { ContentView() }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
1
0
84
3w