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

SwiftUI Documentation

Posts under SwiftUI tag

2,334 Posts
Sort by:
Post not yet marked as solved
0 Replies
19 Views
Environment: Mac OS Sonoma v14.4.1 Xcode 15.3 I'm new to iOS Swift development environment and trying to create a simple app to just return the current location address. I'm testing it with simulator iPhone 15 but the app is not returning any result. Please advise. Here is my code. import SwiftUI import CoreLocation struct CurrentLocationView: View { @StateObject private var locationManager = LocationManager() var body: some View { VStack { Text("Your Address:") .font(.title2) Text(locationManager.address ?? "Locating...") .multilineTextAlignment(.center) .padding() } .onAppear { locationManager.requestAuthorization() } } } class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() @Published var address: String? override init() { super.init() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest } func requestAuthorization() { switch locationManager.authorizationStatus { case .notDetermined: locationManager.requestWhenInUseAuthorization() case .authorizedWhenInUse, .authorizedAlways: locationManager.startUpdatingLocation() case .denied, .restricted: // Handle denied or restricted authorization print("Location services denied") default: break } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let location = locations.first else { return } let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(location) { [weak self] placemarks, error in guard let self = self, let placemark = placemarks?.first else { return } // Extract address components if let thoroughfare = placemark.thoroughfare, let locality = placemark.locality { let address = "\(thoroughfare), \(locality)" self.address = address } else { self.address = "Unable to determine address" } } } } #Preview { CurrentLocationView() }
Posted
by
ktl
Post not yet marked as solved
0 Replies
22 Views
Hi, I am developing a drawing app using SafariView and is using apple pencil double tap handler for crucial features. In IOS 17.5 I lost functionality of it when interacting with SafariView, my friend confirmed that it worked with IOS 17.4 and I can confirm it also worked with IOS 17.1. However, I cannot downgrade my system nor can my uses. THIS IS A FATAL MALFUNCTION FOR MY APP. Detailedly, as I tested, the double tap handlers cannot be activated when my last tapped component is SafariView, so it never works when interacting with my web app. But I can enable this by clicking outside the SafariView or some non-SafariView component on top of it, just anything other than the Safari view, even webkit view can work but it is not usable for me. My aim is to keep listening to double tapping while interacting with SafariView in full screen, so I cannot let the user tap elsewhere to just activate double tap, there is no other walk around for me, unless there is a way to enable 120fps animation in WebKit view, which is only available in safari feature flags as I know. I would like to hear a solution in this situation or a promise of a fix, this is devastating to my users' experience. code to reproduce: import SwiftUI import WebKit import SafariServices struct SafariView: UIViewControllerRepresentable { let url: URL func makeUIViewController(context: Context) -> SFSafariViewController { return SFSafariViewController(url: url) } func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) { // No update code needed for this example } } struct WKWebViewWrapper: UIViewRepresentable { let url: URL func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() let request = URLRequest(url: url) webView.load(request) return webView } func updateUIView(_ uiView: WKWebView, context: Context) { // No update code needed for this example } } struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) .onPencilDoubleTap { value in print("tap1") } Text("Hello, world!") .padding() SafariView(url: URL(string: "https://www.example.com")!) .onPencilDoubleTap { value in print("tap2")} .frame(width:300) WKWebViewWrapper(url: URL(string: "https://www.example.com")!).onPencilDoubleTap { value in print("tap3") } .frame(width:300) } } } #Preview { ContentView() }
Posted
by
XLL
Post not yet marked as solved
0 Replies
40 Views
Hello everyone. I am developing an application with SwiftUI. I am having trouble with NavigationStack(path: ). 1st problem: After the application runs, after clicking on the first list item, there is a flicker in the title section. I think it is the .navigationDestination that causes this problem, because when I change the navigationLink to Button in the “ActiveRegQueryView” screen, this problem disappears. 2nd Problem: When you click on a list item, sometimes it stays pressed (grayed out) and does not take you to the screen (Video 1). If you try to click on an item more than once, navigatinLink passes more than one value to path and opens more than one page (I noticed this with path.count) (Video 2). I don't have this problem if you edit the back button on the screen it takes you to (ActiveRegDetailView). (vm.path.removeLast()) The reason I use path is to close multiple screens and return to the start screen. Video 1: Video 2: Main View: import SwiftUI struct ActiveRegView: View { @Environment(NavigationViewModel.self) private var navViewModel @AppStorage("sortOption") private var sortOrder: sorting = .byBrand @State private var searchText = "" var body: some View { @Bindable var navViewModel = navViewModel NavigationStack(path: $navViewModel.path) { // <- if i don't use path everything is OK List { ActiveRegQueryView(searchText: searchText, sortOrder: sortOrder) // <- Dynamic Query View } .navigationDestination(for: Registration.self, destination: { ActiveRegDetailView(reg: $0) .toolbar(.hidden, for: .tabBar) }) } } } Dynamic Query View: import SwiftData import SwiftUI struct ActiveRegQueryView: View { @Query private var regs: [Registration] @Environment(NavigationViewModel.self) var vm init(searchText: String, sortOrder: sorting) { var order: SortDescriptor<Registration> switch sortOrder { case .byBrand: order = SortDescriptor(\.brand) case .byDateDescending: order = SortDescriptor(\.entryRegistration.entryDate, order: .reverse) case .byDateAscending: order = SortDescriptor(\.entryRegistration.entryDate) } _regs = Query(filter: #Predicate { if !searchText.isEmpty { if $0.activeRegistration && ($0.brand.localizedStandardContains(searchText) || $0.model.localizedStandardContains(searchText) || $0.plate.localizedStandardContains(searchText)) { return true } else { return false } } else { return $0.activeRegistration } }, sort: [order]) } var body: some View { ForEach(regs) { reg in NavigationLink(value: reg) { ListRowView(reg: reg) } // Button { // vm.path.append(reg) // } label: { // ListRowView(reg: reg) // } // .buttonStyle(.plain) } } } I look forward to your ideas for solutions. Thank you for your time.
Posted
by
Post not yet marked as solved
2 Replies
69 Views
Hello, I have a view have three textfields and a button. I wrote following code to move between textfields using return key. func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField == self.A { self.B.becomeFirstResponder() }else if textField == self.B { self.C.becomeFirstResponder() } return true } when I use return key between A->B, above code works properly. but when i use return key between B->C, above code doesn't work. I couldn't figure out what's wrong with this. if anyone pick me my mistake and suggest solution for it, I'd very appreciate. Thanks, c00012
Posted
by
Post not yet marked as solved
2 Replies
97 Views
I am trying to load and view several locations onto a map from a JSOPN file in my SwiftUI project, but I continually encounter the error "no exact matches in call to initializer" in my ContentView.swift file. What I Am Trying to Do: I am working on a SwiftUI project where I need to display several locations on a map. These locations are stored in a JSON file, which I have successfully loaded into Swift. My goal is to display these locations as annotations on a Map view. JSON File Contents: coordinates: latitude and longitude name: name of the location uuid: unique identifier for each location Code and Screenshots: Here are the relevant parts of my code and the error I keep encountering: import SwiftUI import MapKit struct ContentView: View { @State private var mapPosition = MapCameraPosition.region( MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194), span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05) ) ) @State private var features: [Feature] = [] var body: some View { NavigationView { Map(position: $mapPosition, interactionModes: .all, showsUserLocation: true) { ForEach(features) { feature in Marker(coordinate: feature.coordinate) { FeatureAnnotation(feature: feature) } } } .onAppear { POILoader.loadPOIs { result in switch result { case .success(let features): self.features = features case .failure(let error): print("Error loading POIs: \(error.localizedDescription)") } } } .navigationBarTitle("POI Map", displayMode: .inline) } } } struct FeatureAnnotation: View { let feature: Feature var body: some View { VStack { Circle() .strokeBorder(Color.red, lineWidth: 2) .background(Circle().foregroundColor(.red)) .frame(width: 20, height: 20) Text(feature.name) } } } I have not had any luck searching for solutions to my problems using the error messages that keep arising. Does anyone have any advice for how to move forward?
Posted
by
Post marked as solved
1 Replies
85 Views
Map(initialPosition: .camera(mapCamera)) { Marker("Here", coordinate: location) } .frame(height: 300) .clipShape(RoundedRectangle(cornerSize: CGSize(width: 10, height: 10))) .onMapCameraChange(frequency: .continuous) { cameraContext in locationManager.location = cameraContext.camera.centerCoordinate } .onReceive(locationManager.$location, perform: { location in if let location { mapCamera.centerCoordinate = location } }) class LocationDataManager: NSObject, CLLocationManagerDelegate, ObservableObject { enum LoadingState { case loading case notLoading case finished } static let shared = LocationDataManager() private let locationManager = CLLocationManager() @Published var location: CLLocationCoordinate2D? = nil @Published var loading: LoadingState = .notLoading override init() { super.init() locationManager.delegate = self } func resetLocation() { loading = .notLoading location = nil } func getLocation() { locationManager.requestLocation() loading = .loading } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { location = locations.first?.coordinate if location != nil { loading = .finished } } func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) { print("Failed to retrieve location: \(error.localizedDescription)") loading = .notLoading } } So the when the LocationButton is selected, the location is found and the marker is set correctly. You can also move the camera around to adjust the marker position, which works correctly. However, if you press the LocationButton again, it updates the marker position but it won't move the MapCamera to the new location. I can see the marker move. mapCamera.centerCoordinate = location should be doing it, but it's not. Anyone know how to fix this?
Posted
by
Post not yet marked as solved
2 Replies
76 Views
No matter what I have tried, I can't get my test "What would you like to do?" to appear at the top of the screen. What have I missed? Is something g to do with the ZStack? import SwiftUI import SwiftData struct ContentView: View { @Environment(\.modelContext) private var context @Query private var readings: [Readings] @State private var readingTimeStamp: Date = Date() var body: some View { ZStack { Image("IPhone baqckgound 3") .resizable() .aspectRatio(contentMode: .fill) .padding(.top, 40) VStack { Text("What would you like to do?") .font(.title) .fontWeight(.bold) } .padding() Spacer() } } }
Posted
by
Post not yet marked as solved
0 Replies
59 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
Post not yet marked as solved
1 Replies
110 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
by
Post not yet marked as solved
1 Replies
65 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
by
Post not yet marked as solved
5 Replies
124 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
by
Post not yet marked as solved
0 Replies
82 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
Post not yet marked as solved
3 Replies
130 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
by
Post not yet marked as solved
0 Replies
103 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
Post not yet marked as solved
0 Replies
103 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
by
Post not yet marked as solved
0 Replies
82 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
Post not yet marked as solved
1 Replies
129 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
Post not yet marked as solved
1 Replies
97 Views
Document based app on 17.5 has two back buttons, but 17.0 as only one. Did anyone experience this?
Posted
by