Post not yet marked as solved
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()
}
Post not yet marked as solved
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()
}
Post not yet marked as solved
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.
Post not yet marked as solved
I am trying to develop an app that runs on iMacs, iPhones and iPads. so how, using SwiftUI, do I check what device I am running on?
Post not yet marked as solved
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
Post not yet marked as solved
#Preview, @available(iOS 17, *), PreviewProvider
Preview is not working.
I've tried this and that, but I can't.
Please help me.
Post not yet marked as solved
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?
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?
Post not yet marked as solved
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()
}
}
}
Post not yet marked as solved
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()
}
}
Post not yet marked as solved
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 !
Post not yet marked as solved
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.
Post not yet marked as solved
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
Post not yet marked as solved
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
Post not yet marked as solved
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
}
Post not yet marked as solved
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?
Post not yet marked as solved
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.
Post not yet marked as solved
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.
Post not yet marked as solved
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()
)
}
}
Post not yet marked as solved
Document based app on 17.5 has two back buttons, but 17.0 as only one. Did anyone experience this?