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

Post

Replies

Boosts

Views

Activity

OnReceive from RCP not functioning
A timeline in RCP will post a notification "Identifier: Completed" when it finishes playing I am trying to receive this in the following way: extension Notification.Name { static let notifyOnAnimationCompleted = Notification.Name("Completed") } // in the view private let AnimationCompleted = NotificationCenter.default.publisher(for: .notifyOnAnimationCompleted) RealityView {...} .onReceive(AnimationCompleted) { _ in print("End") } This was once working back to July, but it never prints "End" for now
0
0
13
1h
Document-Based App with MVVM
ExampleCode.txt Dear all, I made an app for computing Finite Element Analysis of electric motors. I (think I) managed to follow the MVVM principle by not exposing the model to the views. Now, my goal is to be able to use documents, each representing a different motor. I want to have my files saved on iCloud, and I want to be able to read plain text from it, so some other code (i.e. python) can create new configurations, even though this app is made for building, graphically. Before trying to work with FileDocument, my class ViewModel: ObservableObject had properties with Published, like @Published var staOD = 80.0, and I would have views with TextFields to change these values. Now, I’m trying to blend in FileDocument, and I’m lost. I don’t know how I should work with my data. Under the “Separation of Concerns”, I guessed that: ViewModel: Should handle computations, updates, and application logic. Document: Should focus on data persistence and encapsulate data to be saved/loaded as a document. My ViewModel looks a bit strange to me, and I’m not sure I’m updating it the right way. I have around 100 parameters, I’m afraid I’m updating these parameters too often and unnecessarily every parameter at the same time, even when only one value is changed in the document. What I’m asking: Clarifications on how to work with FileDocument in my case of MVVM (I’m open to change the entire workflow, my main knowledge is on the Model built in Swift, but not SwiftUI) Why isn’t the computed area on the DocumentView at the right value when I open a document? I would like to open documents and have it in the “right” state. In reality, I’m computing an image of the electric motor, and it would be nice to open the document and see the “real” image, and not a dummy image before I can validate the geometry. I have these warnings popping every time I open a document and that scares me, especially because I want ideally to use swift 6 in the coming future, with concurrency the right way. Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates. Thanks a lot for your help, Guillaume I made an example/simplified code that has all the logic. I can't show the entire code in this prompt due to space limitation. Therefore, I put everything (184 lines) in a single Swift file for you to download. You can just create a Multiplatform Document App. Remove all files except the ...App file, in which you can paste the content of the shared swift file. Run on iPhone simulator. Development environment: Xcode 16, macOS 15 Run-time configuration: iOS 18, macOS 15 Open the app, click on "New motor" You will see "Computed area: 3'063..." Click on "Geometry", change "Stator OD" to 60 instead of 80. Click on "Save" button, now Computed area is 863... Click on "Cancel" button, and reopen the same document Problem: area is again 3'063 while when you open Geometry, you see that "Stator OD" is rightfully 60.
0
0
36
5h
How to wrangle Sendable ReferenceFileDocument and SwiftUI
I recently circled back to a SwiftUI Document-based app to check on warnings, etc. with Xcode 16 and Swift 6 now released. I just found a suite a new errors that indicate that ReferenceFileDocument is now expected to be Sendable, which seems very off for it fundamentally being a reference type. I followed the general pattern from earlier sample code: Building Great Apps with SwiftUI, which goes from an Observable object to adding conformance to ReferenceFileDocument in an extension. But then the various stored properties on the class cause all manner of complaint - given that they're not, in fact, sendable. What is an expected pattern that leverages a final class for the ReferenceDocument, but maintains that Sendability? Or is there a way to "opt out" of Sendability for this protocol? I'm at a bit of a loss on the expectation that ReferenceFileDocument is sendable at all, but since it's marked as such, I'm guessing there's some path - I'm just not (yet) clear on how to accomodate that.
1
0
52
6h
SwiftUI iOS18 Bug: 'contextMenu' does not recognize 'scaleEffect' and similar outside of 'ScrollView' parent
The Issue I am building a MessageChannelView, I take most advantage of all ScrollView mechanics by flipping it on it's head with .scaleEffect(y: -1), and then the content inside of it again with .scaleEffect(y: -1), so the content is back to normal. Putting .contextMenu() on any of the elements flipped back to normality will cause an ugly bug on iOS18, but not on iOS17. This is because .contextMenu() on iOS18 does not recognize the .scaleEffect(y: -1) outside of it's ScrollView parent. Minimal Replication 1.) Create any View with SwiftUI similar to this: ScrollViewReader { scrollView in ScrollView { VStack { Text("Test!") .contextMenu { Button(action: {}) { Label("Copy Link", systemImage: "doc.on.doc") } } } .scaleEffect(y: -1) } .scaleEffect(y: -1) } 2.) Run on a physical device with iOS18 More I tested this on three different physical iPhone devices, iOS16, iOS17 and my main device iOS18. The bug only exists on iOS18.
0
0
50
8h
How to permanently move Command+A focus from SideBar to DetailView?
My NavigationSplitView is very simple. The DetailView contains Table populated with data. SideBar populated with items that act as a filter for Table content. If I'm on the SideBar and hit Command-A, I never want to select everything in the sidebar. I always want to select all the content for a detail view. This is how Finder works. I tried to set List(...) { ... } .focusable(false) When I launch the application, Command-A works exactly as I would like. But when I select another "filter" in sidebar with the mouse, the List becomes focusable.
0
0
42
11h
Unable to change UITabbar Background color in iOS 18 for ipad
I am trying to change UITabBar background color runtime as theme changed. It is already working in iOS 17 as I am updating UITabBar.appearance().barTintColor and tintColor But for iOS first i need to change because I don't want that new elevated tabbar so I create custom tabbar controller as described in https://stackoverflow.com/questions/78631030/how-to-disable-the-new-uitabbarcontroller-view-style-in-ipados-18 Accepted Answer by awulf. And by doing this, My tabbar looks same like Old and it is working in iPhone and ipad for iOS 16, iOS 17 and iOS 18 too. But the issue is that I am unable to change my tabbar background color. I have also checked this forum: https://forums.developer.apple.com/forums/thread/761056 But not able to change I have set below 3 properties but no effect let appearance = UITabBar.appearance() appearance.backgroundColor = appearance.barTintColor = appearance.tintColor = I have created CustomTabBarController in storyboard and all working fine Also the appearance changed only once per application lifecycle. It will change color by restarting the app then it will pick last selected theme and the colors are changed. but not able to change colors runtime I have also did below code for reloading purpose tabBar.setNeedsLayout() tabBar.setNeedsDisplay() But nothing work
0
0
51
12h
Button icon in List to match style?
I am trying to figure out how to set a button's label icon to match the button style when inside a list. These four buttons display differently depending on context – if put inside a List or a VStack: Button(role: .destructive) {} label: { Label("Test", systemImage: "figure") }.buttonStyle(.automatic) Button(role: .destructive) {} label: { Label("Test", systemImage: "figure") }.buttonStyle(.bordered) Button {} label: { Label("Test", systemImage: "figure") }.buttonStyle(.borderedProminent) Button(role: .destructive) {} label: { Label("Test", systemImage: "figure") }.buttonStyle(.borderedProminent) Inside a List, which looks weird in my opinion. For reference, this is what they look like inside a VStack, which is what I'd expect: I am not sure if this is intentional or a bug. If there are any workaround which do not explicitly set a specific color, like .foreground(.red), please let me know.
1
0
58
15h
SwiftUI LongPressGesture does not work as expected in Xcode Version 16.0 (16A242) and iOS 18
When I copy and paste example code in apple developer documentation, LongPressGesture does not work as expected in Xcode Version 16.0 (16A242) and iOS 18. It seems updating(_:body:) method does not work when used with LongPressGesture. When I make a breakpoint in updating(_:body:) method and long press the blue circle on the screen of simulator(or device), it is expected to be caught in breakpoint or it is expected that color of circle turns from blue to red to green. However, it is not caught in breakpoint and never turns to red. Question of Stackoverflow is about same issue and I can not use onLongPressGesture method to implement required feature of my app. I submitted bug report via Feedback Assistant and my report's ID is FB15127375 and FB15173175. Please tell me if there is any investigation about this issue. Development environment: Xcode Version 16.0 (16A242), macOS 14.5 Run-time configuration: iOS 18.0
1
0
28
20h
Cannot convert value of type '[Lesson]' to expected argument type 'Binding<C>' and Generic parameter 'C' could not be inferred
I have a problem with ForEach loop, and when i debug the program there appear a problems: Cannot convert value of type '[Lesson]' to expected argument type 'Binding' Generic parameter 'C' could not be inferred Please help me import SwiftUI import Foundation struct ContentView: View { var lessons: [Lesson] = [] let todaysDate = Date() let lessonTime = Date()...Date().addingTimeInterval(45*60) let startProgress = Date().addingTimeInterval(-60) let endProgress = Date().addingTimeInterval(60) @State private var currentLesson: String = "Przerwa" var body: some View { let liveHourString = todaysDate.formatted(date: .omitted, time: .shortened) let liveHourString = "9:10" let liveWeekdayString = todaysDate.formatted(Date.FormatStyle().weekday(.wide)) ForEach(lessons) { lesson in if lesson.startTime <= liveHourString && lesson.endTime >= liveHourString && lesson.dayOfWeek == liveWeekdayString { currentLesson = lesson.name currentLessonStart = lesson.startTime } } VStack { ProgressView(timerInterval: startProgress...endProgress, countsDown: false) { Text(currentLesson) } currentValueLabel: { Text(currentLessonStart...endProgress) } .padding([.top, .leading, .trailing], 15.0) NavigationView{ List(lessons) { lesson in if lesson.dayOfWeek == todaysDate.formatted(Date.FormatStyle().weekday(.wide)) { VStack(alignment: .leading){ Text(lesson.name) Text("\(lesson.startTime) - \(lesson.endTime)") .foregroundStyle(.secondary) Text(lesson.room) .foregroundStyle(.secondary) } } } .navigationBarTitle(Text("Today's Lessons")) } } } } #Preview { ContentView(lessons: testData) } And i have also this file: struct Lesson: Identifiable { var id = UUID() var name: String var room: String var startTime: String var endTime: String var dayOfWeek: String } #if DEBUG let testData = [ //MONDAY Lesson(name: "Programowanie Aplikacji Webowych", room: "J3", startTime: "8:00", endTime: "8:45", dayOfWeek: "Monday"), Lesson(name: "Programowanie Aplikacji Webowych", room: "J3", startTime: "8:50", endTime: "9:35", dayOfWeek: "Monday"), Lesson(name: "Programowanie Aplikacji Webowych", room: "J3", startTime: "9:40", endTime: "10:25", dayOfWeek: "Monday"), Lesson(name: "Język Angielski", room: "Y2", startTime: "10:45", endTime: "11:30", dayOfWeek: "Monday"), Lesson(name: "Język Niemiecki", room: "Y4", startTime: "11:40", endTime: "12:25", dayOfWeek: "Monday"), Lesson(name: "Język Angielski", room: "Y2", startTime: "12:35", endTime: "13:20", dayOfWeek: "Monday"), Lesson(name: "Matematyka", room: "B10", startTime: "13:25", endTime: "14:10", dayOfWeek: "Monday"), //TUESDAY Lesson(name: "WF", room: "Sala Gimnastyczna", startTime: "8:50", endTime: "9:35", dayOfWeek: "Tuesday"), Lesson(name: "WF", room: "Sala Gimnastyczna", startTime: "9:40", endTime: "10:25", dayOfWeek: "Tuesday"), Lesson(name: "Programowanie Aplikacji Desktopowych", room: "X7", startTime: "10:45", endTime: "11:30", dayOfWeek: "Tuesday"), Lesson(name: "Programowanie Aplikacji Desktopowych", room: "X7", startTime: "11:40", endTime: "12:25", dayOfWeek: "Tuesday"), Lesson(name: "Testowanie i Dokumentowanie Aplikacji", room: "J5", startTime: "12:35", endTime: "13:20", dayOfWeek: "Tuesday"), Lesson(name: "Testowanie i Dokumentowanie Aplikacji", room: "J5", startTime: "13:25", endTime: "14:10", dayOfWeek: "Tuesday"), Lesson(name: "Projektowanie Oprogramowania", room: "J5", startTime: "14:15", endTime: "15:00", dayOfWeek: "Tuesday"), Lesson(name: "Projektowanie Oprogramowania", room: "J5", startTime: "15:05", endTime: "15:50", dayOfWeek: "Tuesday"), //WEDNESDAY Lesson(name: "Programowanie Aplikacji Mobilnych", room: "X1", startTime: "8:00", endTime: "8:45", dayOfWeek: "Wednesday"), Lesson(name: "Programowanie Aplikacji Mobilnych", room: "X1", startTime: "8:50", endTime: "9:35", dayOfWeek: "Wednesday"), Lesson(name: "Matematyka", room: "B10", startTime: "9:40", endTime: "10:25", dayOfWeek: "Wednesday"), Lesson(name: "Matematyka", room: "B10", startTime: "10:45", endTime: "11:30", dayOfWeek: "Wednesday"), Lesson(name: "Język Polski", room: "A7", startTime: "11:40", endTime: "12:25", dayOfWeek: "Wednesday"), Lesson(name: "Język Polski", room: "A7", startTime: "12:35", endTime: "13:20", dayOfWeek: "Wednesday"), Lesson(name: "Historia", room: "L5", startTime: "13:25", endTime: "14:10", dayOfWeek: "Wednesday"), //THURSDAY Lesson(name: "Chemia", room: "C7", startTime: "8:00", endTime: "8:45", dayOfWeek: "Thursday"), Lesson(name: "WoS", room: "C8", startTime: "8:50", endTime: "9:35", dayOfWeek: "Thursday"), Lesson(name: "Matematyka", room: "B10", startTime: "9:40", endTime: "10:25", dayOfWeek: "Thursday"), Lesson(name: "Programowanie Obiektowe", room: "X1", startTime: "10:45", endTime: "11:30", dayOfWeek: "Thursday"), Lesson(name: "Programowanie Obiektowe", room: "X1", startTime: "11:40", endTime: "12:25", dayOfWeek: "Thursday"), Lesson(name: "Język Polski", room: "A7", startTime: "12:35", endTime: "13:20", dayOfWeek: "Thursday"), //FRIDAY Lesson(name: "Język Angielski", room: "Y2", startTime: "8:00", endTime: "8:45", dayOfWeek: "Friday"), Lesson(name: "Chemia", room: "C7", startTime: "8:50", endTime: "9:35", dayOfWeek: "Friday"), Lesson(name: "Geografia", room: "C10", startTime: "9:40", endTime: "10:25", dayOfWeek: "Friday"), Lesson(name: "Matematyka", room: "B10", startTime: "10:45", endTime: "11:30", dayOfWeek: "Friday"), Lesson(name: "Godzina Wychowawcza", room: "C15", startTime: "11:40", endTime: "12:25", dayOfWeek: "Friday"), Lesson(name: "WF", room: "Sala Gimnastyczna", startTime: "12:35", endTime: "13:20", dayOfWeek: "Friday"), Lesson(name: "Biologia", room: "C7", startTime: "13:25", endTime: "14:10", dayOfWeek: "Friday"), ] #endif
3
0
104
1d
Suddenly getting "Trailing closure passed to parameter of type 'Visibility' that does not accept a closure" for toolbars
Not sure exactly what’s going on here. I’ve been building out this little app for the past couple of weeks using Xcode 16 betas, and in a couple of places I have code like this: EditItemView(item: inItem) .toolbar { ToolbarItem { Button(action: { self.printLabel(item: inItem) }) { Label("Print Label", systemImage: "printer.filled.and.paper") } } } Now all of a sudden I'm getting an error on .toolbar: “Trailing closure passed to parameter of type 'Visibility' that does not accept a closure.” Looking at the comment for toolbar, it says this method "specifies the visibility," which is a weird thing for it to do with a name like that. But it also has a deprecation tag that I don't quite understand: @available(macOS, introduced: 13.0, deprecated: 100000.0, renamed: "toolbarVisibility(_:for:)"). The name change makes sense, given the description. But what is the huge deprecation version number? Just a hack? And why is this code no longer compiling? As I'm commenting out instances of this, all my toolbars are failing in this way. ETA: yeah, I finally found the right declaration of .toolbar: func toolbar<Content>(@ViewBuilder content: () -> Content) -> some View where Content : View. It's no longer choosing that one. I hate Swift sometimes. ETA2: I finally whittled it down to it not liking Label for some reason. Replacing that with Image works. But of course, the compiler won't tell me why. ETA3: It's worse than I thought: I tried to make a small test case for a bug, and Label works just fine. Why does my code not?
0
0
104
1d
NSApplicationDelegate open URLs only called after second drop
I want to make a simple droplet application. I've set the document types to include com.adobe.pdf files, and I am now receiving callbacks to the app delegate's application(_:open:) callback when I drop PDFs on the app icon… But not the first time. It doesn't matter how long I wait, or whether the app is already open—the first drop never triggers the callback. All subequent drops work as expected, and I get URLs to all the files dropped. What might be wrong? How can I debug this?
1
0
87
1d
grid and buttons
I would like to create 5 buttons in two rows the first row contains 3 buttons while the second 2 buttons button D should occupy the space occupied by the two buttons at the top A and B while as you can see from the attached image button D is as wide as the others on visualstudio c# I know how to do it but with Xcode Swift I can't find any documentation that can help me
3
0
86
1d
Cocoa application duplicated view
I have a Cocoa application and I'm trying to set up an NSImageView without using story board (using storyboard works just fine tho). Also, I'm kinda new to Cocoa so any advice is appreciated. Anyway so here's the deal, I created a class to encapsulate this image: @interface MyView : NSView { @private NSImageView* imageView; } @end @implementation MyView -(id) initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if(self) { NSRect rect = NSMakeRect(10, 10, 100, 200); imageView = [[NSImageView alloc] initWithFrame:rect]; NSImage* image = [NSImage imageNamed:@"bob.jpeg"]; [imageView setImageScaling:NSImageScaleNone]; [imageView setImage: image]; [self addSubview: imageView]; } return self; } -(id) init { return [self initWithFrame:NSMakeRect(10, 10, 100, 100)]; } - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; // Drawing code here. } @end Now, in the view controller file, in the viewDidLoad I tried to load add this as a subview to get it to display my image: - (void)viewDidLoad { [super viewDidLoad]; MyView *customView = [[MyView alloc] init]; [self.view addSubview:customView]; } This kinda works, except that it loads the image twice, I ended up with two images instead of just one like I intended, what gives? what am I doing wrong here?
1
0
73
1d
WKWebView default SameSite value for cookies is different in iOS18
In iOS18, WKWebView's default cookie SameSite value is Lax. Prior to iOS18, the default value is None. Is this intentional, or a bug? This change is not documented anywhere. I made a sample XCode project (ViewController code below) to show this change. It loads www.apple.com into a WKWebView and prints cookies. That site has several cookies, but it only explicitly sets SameSite to None for one cookie, s_vi. Every other cookie relies on default WKWebView behavior. When looking at cookies, either in the console or in Safari's Web Inspector, the SameSite value differs. If older than iOS18, every cookie has SameSite of None. If iOS18, all cookies except s_vi have SameSIte of Lax. I also tried manually setting the following cookies: testCookie-none with SameSite set to None testCookie-lax with SameSite set to Lax testCookie-strict with SameSite set to Strict testCookie- with SameSite set to an empty string When looking at these cookies, testCookie-none and testCookie- have their SameSite of None if older than iOS18, but are both Lax in iOS18. So, it seems we cannot manually set the SameSIte to None either. I realize updating the server to return the SameSite value would resolve this. However, in my app where I'm struggling with this issue, that server is Salesforce. Only they can update their response headers. Since this change isn't documented by Apple, I am assuming it is a bug and not intentional. Are there any workarounds? Any input by Apple on a fix? Below is the ViewController code, and images of the cookies in Safari's Web Inspector. import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func loadView() { // Create WKWebView let config = WKWebViewConfiguration() webView = WKWebView(frame: .zero, configuration: config) // Allow inspection in Safari debugger webView.isInspectable = true // Track the request to load our website webView.navigationDelegate = self // Manually add four cookies: // testCookie-none with SameSite set to None // testCookie-lax with SameSite set to Lax // testCookie-strict with SameSite set to Strict // testCookie- with SameSite set to an empty string addTestCookies() view = webView } override func viewDidLoad() { super.viewDidLoad() // Load a website let urlString = "https://www.apple.com" self.webView.load(URLRequest(url: URL(string:urlString)!)) } // Once the website loads, print the cookies. func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { WKWebsiteDataStore.default().httpCookieStore.getAllCookies { cookies in for cookie in cookies { print(cookie) } } } /* Manually add the following cookies for domain .apple.com testCookie-none with SameSite set to None testCookie-lax with SameSite set to Lax testCookie-strict with SameSite set to Strict testCookie- with SameSite set to an empty string In older iOS versions, both testCookie-none and testCookie- will have their SameSite as none. In iOS18, no cookie will have SameSite as None. */ func addTestCookies() { let httpCookieStore = WKWebsiteDataStore.default().httpCookieStore for sameSitePolicy in ["none", "lax", "strict", ""] { httpCookieStore.setCookie(HTTPCookie(properties: [ HTTPCookiePropertyKey.path: "/", HTTPCookiePropertyKey.name: "testCookie-"+sameSitePolicy, HTTPCookiePropertyKey.value: "1", HTTPCookiePropertyKey.domain: ".apple.com", HTTPCookiePropertyKey.secure: true, HTTPCookiePropertyKey.sameSitePolicy: sameSitePolicy ])!) } } }
1
0
135
1d
Swift pressesBegan no longer works iOS 18?
Previously this code would trigger fine on pressesBegan in iOS 17 and earlier versions, but no longer works in iOS 18. How can I start capturing pressesBegan in iOS 18? It seems like UIResponder is just not capturing the keyboard anymore? struct ContentView: View { var body: some View { KeyBoardView() } } //To Use in SwiftUI struct KeyBoardView: UIViewRepresentable{ func makeUIView(context: Context) -> KeyEventView { KeyEventView() } func updateUIView(_ uiView: KeyEventView, context: Context) { } class KeyEventView: UIView { init() { super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) { print("test") } } }
0
0
54
1d
Xcode 16 - List Lazy loading broken
In Xcode 16 and Xcode 16.1 beta 2 the lazy loading of list does not work properly. Tested on physical device with iOS 17. Below is minimal code to reproduce this issue: You can see in the debug console how many child views are initialized based on the print statement. import SwiftUI @main struct TestDemoApp: App { let data = Array(1...1000) var body: some Scene { WindowGroup { List(data, id: \.self) { item in SomeView(item: item) } } } } struct SomeView: View { static var count = 0 let item: Int init(item: Int){ self.item = item Self.count += 1 print(Self.count) } var body: some View{ Text(String(item)) .frame(height: 100) } } When the view is shown the List creates all child views at once as shown in the console output: It does not loads only first 13 out of 1000 as it does in older xcode 15.2: As the List is quite often used component in Swiftui Apps, the apps will be slow, because all the data are loaded and the main thread will be stuck until all child views are loaded.
1
0
78
1d