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

SwiftUI Documentation

Posts under SwiftUI tag

2,332 Posts
Sort by:
Post not yet marked as solved
4 Replies
249 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
2 Replies
49 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
0 Replies
40 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
86 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
73 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
66 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
142 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
89 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
50 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
66 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
58 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
536 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
83 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
119 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
879 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
.
Post not yet marked as solved
1 Replies
221 Views
Sonoma 14.4.1 (did not test on 14.4) Xcode 15.3 New Project macOS Document App Run View menu has "Enter Full Screen" Do Command-N View menu does not have "Enter Full Screen" May need to open and close a few windows. import SwiftUI @main struct testApp: App { var body: some Scene { DocumentGroup(newDocument: testDocument()) { file in ContentView(document: file.$document) } .commands { CommandGroup(replacing: CommandGroupPlacement.saveItem) { } } } } File menu Open Recent becomes NSMenuItem
Posted Last updated
.
Post not yet marked as solved
6 Replies
537 Views
TabView { SummaryView() .toolbar(.hidden, for: .tabBar, .bottomBar) .tabItem { Text("Title.Summary") } .tag(TabItems.summary) CalendarView() .toolbar(.hidden, for: .tabBar, .bottomBar) .tabItem { Text("Title.Calendar") } .tag(TabItems.calendar) EventTypeView() .toolbar(.hidden, for: .tabBar, .bottomBar) .tabItem { Text("Title.EventType") } .tag(TabItems.group) LectureView() .toolbar(.hidden, for: .tabBar, .bottomBar) .tabItem { Text("Title.Lecture") } .tag(TabItems.lecture) NotificationView() .toolbar(.hidden, for: .tabBar, .bottomBar) .tabItem { Text("Title.Notifications") } .tag(TabItems.notification) } Tabbar is hidden when first opened but tabbar is appeared when I change tab selection. I tested it on iOS 17.1, iOS 17.4, and this bug is only appeared in iOS 17.4.
Posted
by LeeJaeho.
Last updated
.
Post not yet marked as solved
1 Replies
103 Views
Fairly new to SwiftUI and using it for a school project. I keep getting this error and I have no idea how to fix it. // AddToCartButton.swift // ProducePal // import SwiftUI struct AddToCartButton: View { @EnvironmentObject var multicart: MultiCartManager var product: Product var body: some View { VStack { Button { multicart.addToCart2(product: product) } label: { Text("Add to Cart") .font(.headline) .fontWeight(.semibold) .foregroundColor(.white) .padding() .padding(.horizontal, 20) .background(Color.blue) .cornerRadius(10) .shadow(radius: 20) } } .buttonStyle(PlainButtonStyle()) } } struct AddToCartButton_Previews: PreviewProvider { static var previews: some View { AddToCartButton(product: productList[0]) .environmentObject(MultiCartManager()) } }
Posted
by lilharlow.
Last updated
.
Post not yet marked as solved
1 Replies
110 Views
Using SwiftUI how can I get the click of a "Button" to change the wording of a "Label" and/or "Text" Field? I have tried:- let myLabel = Label { Text("Text to be Changed" .foregrorundStyle ...... } icon: { ...... } .... ..... Button("Change Label Wording"){ myLabel.stringValue = "Changed text" } This gives me two problems (at least): I cannot get the label to display The myLabel.stringValue = "Changed text gives me the error: Type '()' cannot conform to 'View' Value of type 'Label<some View, some View>' has no member 'stringValue' What have I done wrong?
Posted
by jamesm46.
Last updated
.
Post not yet marked as solved
0 Replies
90 Views
I have encountered a strange behavior these past couple weeks while dealing with Bluetooth, mostly because my code hasn't changed in over 6 months (maybe it was not working before and now it's correct, who knows). Essentially, when i pair with a bluetooth device for the first time, the onchange has stopped firing. I can post more exact code of the view but I didn't think it was necessary but after you select the device you want to connect to (for the first time) you get asked by the OS to pair. After successful connection, we read information from the device (the Profiles). Once I get that information, i set dataGathered to true which triggers .onChange and I can navigate. However, with this initial connection/pairing the .onChange is never triggered, but i know i'm getting my dataGathered set to true because my print is being set. Subsequent connections do cause .onChange to be triggered with 0 profiles and with many profiles. This code hasn't changed in months so i'm not sure if there's SwiftUI bug that's sprung up or what, or if there's an inherint issue with what i was doing and it's only now being caught. struct DeviceSearchView: View { @StateObject var connectedManager: Manager = Manager() @StateObject var bluetoothListener: Listener = BluetoothListener() var body: some View { body .onChange(self.bluetoothListener.connectedDevice) { device in device.getData() } .onChange(self.connectedManager.dataGathered) { dataGathered in // determine navigation } } } Manager Object final class Manager: ObservedObject, BTDelegate, Identifiable /*i've tried adding/switching with Equatable but no change*/ { @Published var dataGathered: Bool = false @Published var profileList: Profile = [Profile]() @Published var index: Int = 0 func updatedProfile(list: NSArray, selectedIndex: Int) { print("profiles are in fact here") var newList = [Profile]() for element in list { if let profile = element as? B50Profile { print("\(profile.name)") if !newList.contains(profile){ newList.append(profile) } } } self.profileList = newList self.index = selectedIndex self.dataGathered = true print("data gathered is \(self.dataGathered)" } }
Posted
by ken-kun.
Last updated
.