Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

SwiftUI Documentation

Posts under SwiftUI tag

2,331 Posts
Sort by:
Post not yet marked as solved
0 Replies
20 Views
hello I am trying to detect the orientation of text in images. (each image has a label with a number but sometimes the the label is not in the right orientation and I would like two detect these cases and add a prefix to the image files) this code is working well but when the text is upside down it considers that the text is well oriented is it a way to distinguish the difference ? thanks for your help ! import SwiftUI import Vision struct ContentView: View { @State private var totalImages = 0 @State private var processedImages = 0 @State private var rotatedImages = 0 @State private var remainingImages = 0 var body: some View { VStack { Button(action: chooseDirectory) { Text("Choisir le répertoire des images") .padding() } Text("TOTAL: \(totalImages)") Text("TRAITEES: \(processedImages)") Text("ROTATION: \(rotatedImages)") Text("RESTANT: \(remainingImages)") } .padding() } func chooseDirectory() { let openPanel = NSOpenPanel() openPanel.canChooseDirectories = true openPanel.canChooseFiles = false openPanel.allowsMultipleSelection = false openPanel.begin { response in if response == .OK, let url = openPanel.url { processImages(in: url) } } } func processImages(in directory: URL) { DispatchQueue.global(qos: .userInitiated).async { do { let fileManager = FileManager.default let urls = try fileManager.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) let imageUrls = urls.filter { $0.pathExtension.lowercased() == "jpg" || $0.pathExtension.lowercased() == "png" } DispatchQueue.main.async { self.totalImages = imageUrls.count self.processedImages = 0 self.rotatedImages = 0 self.remainingImages = self.totalImages } for url in imageUrls { self.processImage(at: url) } } catch { print("Error reading contents of directory: \(error.localizedDescription)") } } } func processImage(at url: URL) { guard let image = NSImage(contentsOf: url), let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return } let request = VNRecognizeTextRequest { (request, error) in if let error = error { print("Error recognizing text: \(error.localizedDescription)") return } if let results = request.results as? [VNRecognizedTextObservation], !results.isEmpty { let orientationCorrect = self.isTextOrientationCorrect(results) if !orientationCorrect { self.renameFile(at: url) DispatchQueue.main.async { self.rotatedImages += 1 } } } DispatchQueue.main.async { self.processedImages += 1 self.remainingImages = self.totalImages - self.processedImages } } let handler = VNImageRequestHandler(cgImage: cgImage, options: [:]) do { try handler.perform([request]) } catch { print("Error performing text recognition request: \(error.localizedDescription)") } } func isTextOrientationCorrect(_ observations: [VNRecognizedTextObservation]) -> Bool { // Placeholder for the logic to check text orientation // This should be implemented based on your specific needs for observation in observations { if let recognizedText = observation.topCandidates(1).first { let boundingBox = observation.boundingBox let angle = atan2(boundingBox.height, boundingBox.width) if abs(angle) > .pi / 4 { return false } } } return true } func renameFile(at url: URL) { let fileManager = FileManager.default let directory = url.deletingLastPathComponent() let newName = "ROTATION_" + url.lastPathComponent let newURL = directory.appendingPathComponent(newName) do { try fileManager.moveItem(at: url, to: newURL) } catch { print("Error renaming file: \(error.localizedDescription)") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Posted
by cloum.
Last updated
.
Post not yet marked as solved
3 Replies
632 Views
I have an app which uses SwiftUI and Mac Catalyst. When running on a Mac I want to provide a preferences menu entry with the usual keyboard shortcut Command + ,. An implementation via the Settings bundle is out of question since my preferences are too complex for this. Here is a reduced example of my implementation: import SwiftUI @main struct PreferencesMenuTestApp: App { @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate var body: some Scene { WindowGroup { ContentView() } } } class AppDelegate: UIResponder, UIApplicationDelegate { override func buildMenu(with builder: UIMenuBuilder) { let preferencesCommand = UIKeyCommand(title: "Preferences…", action: #selector(showPreferences), input: ",", modifierFlags: .command) // let preferencesCommand = UIAction(title: "Preferences…") { action in // debugPrint("show preferences") // } let menu = UIMenu(title: "Preferences…", options: .displayInline, children: [preferencesCommand]) builder.insertSibling(menu, afterMenu: .about) } @objc func showPreferences() { debugPrint("show preferences") } } The problem is that the menu entry is disabled. Obviously the provided selector is not recognised. When I mark the AppDelegate with @main, then the menu entry is enabled. Of course then the app's window is empty. When I switch to the UIAction implementation (the out commented code) it works fine. But since one cannot provide a keyboard shortcut for UIActions this is not a good solution. What am I missing? How would one implement a preferences menu entry that actually works?
Posted
by RayWo.
Last updated
.
Post not yet marked as solved
3 Replies
644 Views
I recently encountered a difficult-to-diagnose bug in an app that I'm working on, and I thought I would share it with the Apple Developer community. The app that I'm working on is an iOS app that uses Core Location's Visit Monitoring API, and it is essential that the app is able to process incoming visits while running in the background. However, after real-world testing, I discovered several crash reports which were difficult to understand, as SwiftUI symbols are not symbolicated on debug builds. Eventually I discovered that the app was crashing when calling an @EnvironmentObject property of the root ContentView from that view's body when the app was launched directly into the background from not running at all. After creating a small test app to isolate the problem, I discovered that any environment object declared in the App struct and referenced from the root ContentView causes the crash, with the exception message: "Fatal error: No ObservableObject of type ArbitraryEnvObject found. A View.environmentObject(_:) for ArbitraryEnvObject may be missing as an ancestor of this view." It seems that when a SwiftUI app is launched in the background, the ContentView's body is executed, but the environment is not initialized. I searched through as much documentation as I could, but could not find any information about how this should be handled, so I think it's a bug in SwiftUI. I have filed a Feedback Assistant bug report. The current workaround is to convert my ObservableObject into an object that conforms to the new @Observable protocol, add it to the scene as an Environment Value with the .environment(_:) modifier rather than the .environmentObject(_:) modifier, and declare the @Environment property on the view as optional. The object will still be missing when the app is launched in the background, but the optional property can be handled safely to prevent a crash. Attached to this post is a sample project that demonstrates the issue and the workaround. And finally, I'd like to hear from anyone who knows more about the expected behavior of background launches of SwiftUI apps, and whether or not there's something I should be doing completely differently. I'm not able to directly attach a zip archive to this post, so here's an iCloud link to the sample project: BackgroundEnvObjCrash.zip
Posted Last updated
.
Post not yet marked as solved
1 Replies
84 Views
Hello, can someone please explain to me how does SwiftUI TabView works "under the hood" , I don't understand why do all views in TabView get reinitialized each time I switch between tabs. Xcode Version 15.3, iOS 16+ Below is the code snippet : struct ScreenOne: View { init() { print("ScreenOne init called !") } var body: some View { Text("This is screen one!") } } struct ScreenTwo: View { init() { print("ScreenTwo init called !") } var body: some View { Text("This is screen two !") } } struct TabViewTest: View { @State var selectedIndex: Int = 1 var body: some View { TabView(selection: $selectedIndex) { ScreenOne() .tag(1) .tabItem { Text("Item 1") } ScreenTwo() .tag(2) .tabItem { Text("Item 2") } } // .onChange(of: selectedIndex) { oldValue, newValue in // // } // NOTE: When code above is uncommented // Screen one & Screen two initializers get called // each time switch to different tab occurs } } Snippet output with the commented out code : App loads Both print statements get called -> "ScreenOne init called ! & "ScreenTwo init called ! Switch between taps Nothing happens Snippet output with the uncommented code : App loads Both print statements get called -> ScreenOne init called ! & ScreenTwo init called ! Switch between taps Both print statements get called -> ScreenOne init called ! & ScreenTwo init called ! @eskimo heeelp :) Thanks in advance !
Posted Last updated
.
Post not yet marked as solved
1 Replies
47 Views
I am little confused about when to use State / StateObject / ObservedObject. What I have researched and what I understand: @State --> for value types @StateObject --> for reference types @ObservedObject --> child objects who needs reference to above two (the parent object should have @State/@StateObject and the object should conform to Observable) I am clear about Environment object.
Posted Last updated
.
Post not yet marked as solved
5 Replies
106 Views
Gents, dev(il)s, I am looking for a piece of code or principal explanation to realise following: I have a array of struct Item{} Each item has child [Item] in the content view I would like to have a hierarchical displayed tree of my Items and for each Item line I would like to have a button to remove it or add a child item for a selected one I tired List entity, navigation and have no real success. Is anybody there to give me a small guide? Thank you M
Posted Last updated
.
Post not yet marked as solved
4 Replies
265 Views
Hello developers ! I've created a List or a ForEach from a binding where there are TextFields or TextEditors inside. When I go to fill in the text, the keyboard dismisses after one char is typed in ! My need is to be able to add textfields as much as required. Please have a look to this code import SwiftUI struct ContentView: View { @State private var messages = ["Hello 1","Hello 2","Hello 3"] var body: some View { VStack(alignment: .leading) { List($messages, id: \.self) { $msg in TextEditor(text: $msg) } ForEach($messages, id: \.self) { $msg in VStack{ TextEditor(text: $msg) } .contextMenu{ Button(role: .destructive, action: { messages = messages.filter {$0 != msg} }, label:{ Text("Delete entry") }) } } Button(action: { messages.append("-") } , label: { Text("Add a row") }) } .background(.black) .padding() } } #Preview { ContentView() } I'm using iOS 17.4 and Xcode 15.3 Thanks !
Posted
by boujouman.
Last updated
.
Post not yet marked as solved
0 Replies
71 Views
I am trying to bring my iOS App to native macOS. I am using exactly the same TimelineProvider and widgets (the ones not supported on macOS surrounded by #if(os)). Running the whole app or just the WidgetExtension on iOS works perfectly fine. Running the mac app works perfectly fine apart from missing Widgets. When running the WidgetExtension on My Mac, the WidgetKit Simulator opens and only presents Failed to load widget. The operation couldn't be completed. (WidgetKit_Simulator.WidgetDocument.Error error 4.) The code compiles fine without any warnings, only a file path is printed into the console. file:///Users/myName/Library/Developer/Xcode/DerivedData/MyAppName-dfsiuexplidieybwvbkqofchxirp/Build/Products/Debug/MyApp.app/Contents/PlugIns/MyAppNameWidgetExtensionExtension.appex/ Shortly after I get a log entry Logging Error: Failed to initialize logging system. Log messages may be missing. If this issue persists, try setting IDEPreferLogStreaming=YES in the active scheme actions environment variables. I am not sure which further Informationen I can give to solve my problem. Destinations on main App and Widget Extension is both set to Mac (no suffix). The mac is running 14.4.1 and Xcode 15.3. I am really thankful for any assistance you can give me to fix this problem. Thanks
Posted
by FPST.
Last updated
.
Post not yet marked as solved
3 Replies
120 Views
I have a singleton instance of a class that (among other things) is managing which subset of words will be available to users. The contents of availableWords will always be a subset of words and is always a function of three userDefaults that are bound to user settings (using @AppStorage) I could dynamically reconstruct availableWords every time it is needed, but it will be read much more frequently than it changes. Because of this, I want to cache the updated list every time a user changes one of the settings that will change its contents. But the only way I can see to do this is to create an update function and rely on the UI code to call the function any time a user updates one of the settings that will require availableWords to be updated. And this feels more like something out of UIKit. Do any of you see a better way of managing the updates of availableWords? class WordsManager { static let shared = WordsManager() let words: Words // defined in init var availableWords: Words // updated anytime scriptPickers, languageChoice or cardPile changes @AppStorage("scriptPickers") var scriptPickers: ScriptPickers = ScriptPickers.defaultDictionary @AppStorage("languageChoice") var languageChoice: LanguageChoice = .all @AppStorage("cardPile") var cardPile: CardPile = .allRandom func updateAvailableWords() { var result = words.filtered(by: cardPile.wordList) let askIdentifiers = languageChoice.askLanguages let answerIdentifiers = languageChoice.answerLanguages result = result.matching(askIdentifiers: askIdentifiers, answerIdentifiers: answerIdentifiers) self.availableWords = result } // other stuff }
Posted Last updated
.
Post not yet marked as solved
0 Replies
94 Views
I've been encountering a strange crash that occurs randomly on my app's startup. The app compiles and (usually) runs just fine. I have found no methods to consistently reproduce this crash. I would provide the exception backtrace, but for some reason it's being flagged as sensitive language?? So instead I've attached the full crash log for anyone who is interested. Any help resolving this issue would be greatly appreciated.
Posted Last updated
.
Post not yet marked as solved
0 Replies
91 Views
I have a .search field in the toolbar of my swiftui macOS app. it only "drops down" to show a couple items if the window is zoomed to full screen. The first screencap is with window zoomed full screen (incorrect behavior). second screencap is window unzoomed (correct). Any advice?
Posted
by Tafkad.
Last updated
.
Post not yet marked as solved
1 Replies
160 Views
I have a situation where tapping on a NavigationLink on an item from a SwiftData Query results in an infinite loop, causing the app the freeze. If you run the code, make sure to add at least 1 item, then tap on it to see the issue. Here is the code for a small sample app I made to illustrate the issue: import SwiftUI import SwiftData @main struct TestApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ Item.self ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { let container = try ModelContainer(for: schema, configurations: [modelConfiguration]) return container } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } struct ContentView: View { var body: some View { NavigationStack { ListsView() } } } struct ListsView: View { @Environment(\.modelContext) private var modelContext @Query(filter: #Predicate<Item> { _ in true }) private var items: [Item] var body: some View { List(items) { item in NavigationLink { ItemDetail() } label: { VStack { Text("\(item.name) | \(item.date.formatted())") } } } Button("Add") { let newItem = Item(name: "Some item", date: .now) modelContext.insert(newItem) try? modelContext.save() } } } struct ItemDetail: View { private var model = ItemModel() var body: some View { VStack { Text("detail") } } } fileprivate var count = 0 class ItemModel { var value: Int init() { value = 99 print("\(count)") count += 1 } } @Model final class Item { let name: String let date: Date init(name: String, date: Date) { self.name = name self.date = date } } In the test app above, the code in the initializer of ItemModel will run indefinitely. There are a few things that will fix this issue: comment out the private var model = ItemModel() line in ItemDetail view replace the @Query with a set list of Items move the contents of the ListsView into the ContentView instead of referencing ListsView() inside the NavigationStack But I'm not sure why this infinite loop is happening with the initializer of ItemModel. It seems like a SwiftData and/or SwiftUI bug, because I don't see a reason why this would happen. Any ideas? Has anyone run into something similar?
Posted Last updated
.
Post not yet marked as solved
1 Replies
120 Views
I have a complex project that includes a background process sending requests to the backend for updates. It sends requests once per second. So, I have the MyView where the PresetPicker is located. When I open the PresetPicker and try to scroll down, it keeps pushing me back up every second. PresetPicker redraws itself every second due to some changes from the background process. (Turning off the background process confirmed that everything works fine.) I wrapped my PresetPicker in EquatableView, added a bunch of logs triggered by changes/redraws of the PresetPicker, but the logs are empty and EquatableView didn't help. I tried setting breakpoints; they trigger when the PresetPicker first appears but don't trigger afterward. How can I fix/debug this? Here is some code: struct PresetPicker: View, Equatable { var body: some View { Menu { Text("1") Text("2") Text("3") Text("4") } label: { Text("menu") } } } struct MyView: View { var body: some View { EquatableView(content: PresetPicker() ) } }
Posted
by Jonatus.
Last updated
.
Post not yet marked as solved
0 Replies
71 Views
Hello, I'm facing an issue with the volume slider in AVPlayer. Despite setting the volume property and mute property to false, the volume slider does not work as expected. Initially, the volume is muted with the slider set to the minimum. If I change the volume, when I release the slider, it returns to the minimum and the mute icon remains active. However, if I set it to maximum, the setting remains and the icon changes. However, the video volume never changes and remains at the value set in the code. Here is the code I am using: var player: AVPlayer! var playerController: AVPlayerViewController! override func viewDidLoad() { super.viewDidLoad() player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "video", ofType: "mp4")!)) player.volume = 0.5 player.isMuted = false playerController = AVPlayerViewController() playerController.player = player playerController.view.frame = self.view.frame addChild(playerController) view.addSubview(playerController.view) playerController.view.frame = view.bounds playerController.didMove(toParent: self) player.play() } Can someone please help me resolve this issue? Any assistance would be greatly appreciated. Thank you.
Posted
by Luck81.
Last updated
.
Post marked as solved
1 Replies
97 Views
Starting on Xcode 15.3 and 15.4 my SwiftUI Previews stopped working with the following error: == PREVIEW UPDATE ERROR:     LinkDylibError: Failed to build ContentView.swift          Linking failed: linker command failed with exit code 1 (use -v to see invocation)          ld: warning: search path '/Applications/Xcode.app/Contents/SharedFrameworks-iphonesimulator' not found     Undefined symbols for architecture arm64:       "static MyLibrary.DisplayUtil.getText() -> Swift.String", referenced from:           closure #1 () -> SwiftUI.Text in (extension in Demo_Broken_Preview_PreviewReplacement_ContentView_1):Demo_Broken_Preview.ContentView.(__preview__body in _1BA320C8FB5388C953E1E463345C3D72).getter : some in ContentView.1.preview-thunk.o       "type metadata accessor for MyLibrary.DisplayUtil", referenced from:           closure #1 () -> SwiftUI.Text in (extension in Demo_Broken_Preview_PreviewReplacement_ContentView_1):Demo_Broken_Preview.ContentView.(__preview__body in _1BA320C8FB5388C953E1E463345C3D72).getter : some in ContentView.1.preview-thunk.o     ld: symbol(s) not found for architecture arm64     clang: error: linker command failed with exit code 1 (use -v to see invocation) After much trial and error, I narrowed it down to my SwiftUI views using properties or functions inside components in Swift Packages. This is a simple example of my Swift Package: public class DisplayUtil {     public func getText() -> String {         return "Text"     }          public static func getText() -> String {         return "Text"     } } And my SwiftUI View import SwiftUI import MyLibrary struct ContentView: View {     var body: some View {         VStack {             Text(DisplayUtil.getText())         }         .padding()     } } #Preview {     ContentView() } The same code works fine on Xcode 15.2 Link to the sample project: https://www.icloud.com/iclouddrive/0c00AD0esi2PwqqiRggokfwGw#Demo%5FBroken%5FPreview Is anybody else having a similar issue?
Posted
by xlsmearlx.
Last updated
.
Post not yet marked as solved
1 Replies
90 Views
Document based app on 17.5 has two back buttons, but 17.0 as only one. Did anyone experience this?
Posted
by molecule.
Last updated
.
Post not yet marked as solved
4 Replies
549 Views
Hi, community: I was trying to move from application(_:open:options:) (UIKit) to onOpenURL(perform:) (SwiftUI). Maybe there's something that I'm missing. In UIKit you can say to the system that you won't handle the URL then the app is not opened, but when I use onOpenURL(perform:) it is always opened. Is there any way to achieve the same behavior? Thanks in advance.
Posted
by JesusMG.
Last updated
.
Post marked as solved
1 Replies
108 Views
I've run into a problem related to navigation links in child Views containing a SwiftData @Query and a predicate. When tapping on a NavigationLinks, the containing View is invalidated pausing the UI. When tapping back, the View is invalidated a second time during which time the View ignores any new taps for navigation leading to a poor user experience. A complete example: import SwiftUI import SwiftData @Model final class Item { var num: Int init(num: Int) { self.num = num } } @main struct TestSwiftDataApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([Item.self]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true) let container: ModelContainer do { container = try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } // Add some sample data Task { @MainActor in for i in 0...1000 { container.mainContext.insert(Item(num: i)) } } return container }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } extension Color { static func random() -> Color { Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1)) } } struct ContentView: View { var body: some View { NavigationStack { SubView() .navigationDestination(for: Item.self) { item in Text("Item at \(item.num)") } } } } struct SubView: View { @Environment(\.modelContext) private var modelContext @Query(filter: #Predicate<Item> { item in item.num < 20 }, sort: \.num) private var items: [Item] var body: some View { let _ = Self._printChanges() List { ForEach(items) { item in NavigationLink(value: item) { Text("Item \(item.num)") }.background(Color.random()) } } } } The background colors of cells will shift every invalidation. In addition there's some debugging in there to show what's happening. When running it, I get SubView: @self, @identity, _modelContext, @128, @144 changed. SubView: @self changed. SubView: @dependencies changed. Then I tap on an item and it invalidates: SubView: @self changed. Tapping back invalidates it again during which time the UI ignores new taps: SubView: @self changed. The odd thing is, this behavior doesn't happen if the NavigationStack is moved to the child View with the NavigationLinks like this: struct ContentView2: View { var body: some View { SubView2() } } struct SubView2: View { @Environment(\.modelContext) private var modelContext @Query(filter: #Predicate<Item> { item in item.num < 20 }, sort: \.num) private var items: [Item] var body: some View { let _ = Self._printChanges() NavigationStack { List { ForEach(items) { item in NavigationLink(value: item) { Text("Item \(item.num)") }.background(Color.random()) } } .navigationDestination(for: Item.self) { item in Text("Item at \(item.num)") } } } } When running this, there's one less change as well and no invalidations on tap or back: SubView: @self, @identity, _modelContext, @128, @144 changed. SubView: @dependencies changed. The problem also doesn't happen if the @Query does not have a filter #Predicate. Unfortunately, the application in question has a deeper hierarchy where views with a @Query with a predicate can navigation to other views with a @Query and predicate, so neither solution seems ideal. Is there some other way to stop the invalidations from happening?
Posted
by Aloisius.
Last updated
.
Post not yet marked as solved
1 Replies
133 Views
When I run the code below, the trace, "Called", is shown 3-4 times initially. If I click on a color row, the trace shows 9 times. Why is that? If I comment out the line, @Environment(\.dismiss) private var dismiss, the trace shows only 1 time, as expected. I've read a number of reports regarding dismiss() which seems to be very brittle. It often causes an infinite loop. But I need to dismiss a view. Its older counterpart, @Environment(\.presentationMode), seems to cause infinite loop at times. Are there other ways to dismiss a view without suffering these issues? struct TestNavigationLink: View { @Environment(\.dismiss) private var dismiss var body: some View { let _ = print("Called") NavigationStack { List { NavigationLink("Mint") { ColorDetail(color: .mint) } } .navigationTitle("Colors") } } // body struct ColorDetail: View { var color: Color var body: some View { color.navigationTitle(color.description) } } }
Posted
by atluutran.
Last updated
.
Post not yet marked as solved
1 Replies
894 Views
I get this error while migrating from ObservableObject to @Observable. Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context My original code: struct SomeView: View { @StateObject private var viewModel = ViewModel() } After migration: @MainActor @Observable class BaseViewModel { } @MainActor class ViewModel: BaseViewModel { } struct SomeView: View { @State private var viewModel = ViewModel() } As discussed here. It seems like @StateObject is adding @MainActor compliance to my View under the hood because it's wrappedValue and projectedValue properties are marked as @MainActor, while on @State they are not. @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) @frozen @propertyWrapper public struct StateObject&lt;ObjectType&gt; : DynamicProperty where ObjectType : ObservableObject { ... @MainActor public var wrappedValue: ObjectType { get } .... @MainActor public var projectedValue: ObservedObject&lt;ObjectType&gt;.Wrapper { get } } One solution for this is to mark my View explicitly as @MainActor struct ViewModel: View but it have it side effects, for example code like: Button(action: resendButtonAction) { Text(resendButtonAttributedTitle()) } Will result a warning Converting function value of type '@MainActor () -&gt; ()' to '() -&gt; Void' loses global actor 'MainActor' While could be easily solved by using instead Button(action: { resendButtonAction() } ) { Text(resendButtonAttributedTitle()) } I still feel like marking the whole View explicitly as @MainActor is not a good practice. Adding fake @StateObject property to my view also do the trick, but it's a hack (the same for @FetchRequest). Can anyone think of a more robust solution for this?
Posted
by itayAm.
Last updated
.