Post

Replies

Boosts

Views

Activity

Having issues with .sheet and .dismiss()
Hello When I dismiss my .sheet it is very slow and sometimes it doesn't work .sheet(isPresented: $myViewi) {         MyView()       } @Environment(\.presentationMode) var presentationMode .navigationBarItems(trailing:           Button(action: {    presentationMode.wrappedValue.dismiss()                                         }) {                                             Image(systemName: "xmark").font(.title).foregroundColor(.blue)                                         }                 ) How do I fix it? Thank You
2
0
921
Dec ’20
Change Placeholder to a String in a CustomTextField
Hello How do I make the default placeholder of a CustomTextField (that has a double binding) a string (onAppear) When I run the app on the TextField I see 0 instead of "Input" Code: import SwiftUI struct BMIView: View {     var currencyFormatter: NumberFormatter {         let formatter = NumberFormatter()         formatter.locale = .current         formatter.numberStyle = .decimal         return formatter     }     @State private var height: Double?         var body: some View {         NavigationView{             Form{                 Section(header: Text("Enter your height in cm")){                     DecimalTextField("Input", value: $height.bound, formatter: currencyFormatter)                }             }             .navigationBarTitle("BMI")         }     } } struct DecimalTextField: UIViewRepresentable {     private var placeholder: String     @Binding var value: Double     private var formatter: NumberFormatter     init(_ placeholder: String,          value: Binding<Double>,          formatter: NumberFormatter ) {         self.placeholder = placeholder         self._value = value         self.formatter = formatter     }     func makeUIView(context: Context) -> UITextField {         let textfield = UITextField()         textfield.keyboardType = .decimalPad         textfield.delegate = context.coordinator         textfield.placeholder = placeholder         textfield.text = formatter.string(for: value) ?? placeholder         textfield.textAlignment = .left         let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: textfield.frame.size.width, height: 44)) let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(textfield.doneButtonTapped(button:)))         let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace,                                     target: nil,action: nil)         toolBar.setItems([space, doneButton], animated: true)         textfield.inputAccessoryView = toolBar         return textfield     }     func updateUIView(_ uiView: UITextField, context: Context) {         // Do nothing, needed for protocol     }     func makeCoordinator() -> Coordinator {         Coordinator(self)     }     class Coordinator: NSObject, UITextFieldDelegate {         var parent: DecimalTextField         init(_ textField: DecimalTextField) {             self.parent = textField         }         func textField(_ textField: UITextField,                        shouldChangeCharactersIn range: NSRange,                        replacementString string: String) -> Bool {             // Allow only numbers and decimal characters             let isNumber = CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: string))             let withDecimal = (                 string == NumberFormatter().decimalSeparator &&                     textField.text?.contains(string) == false             )             if isNumber || withDecimal,                 let currentValue = textField.text as NSString?             {                 // Update Value                 let proposedValue = currentValue.replacingCharacters(in: range, with: string) as String                 let decimalFormatter = NumberFormatter()                 decimalFormatter.locale = Locale.current                 decimalFormatter.numberStyle = .decimal                 // Try currency formatter then Decimal formatrer                 let number = self.parent.formatter.number(from: proposedValue) ?? decimalFormatter.number(from: proposedValue) ?? 0.0                 // Set Value                 let double = number.doubleValue                 self.parent.value = double             }             return isNumber || withDecimal         }         func textFieldDidEndEditing(_ textField: UITextField,                                     reason: UITextField.DidEndEditingReason) {             // Format value with formatter at End Editing             textField.text = self.parent.formatter.string(for: self.parent.value)         }     } } // MARK: extension for done button extension  UITextField{     @objc func doneButtonTapped(button:UIBarButtonItem) -> Void {         self.resignFirstResponder()     } } extension Optional where Wrapped == Double {          var _bound: Double? {         get{             return self                      }         set{             self = newValue                      }     }          var bound: Double {         get{             return _bound ?? 0         }         set {             _bound = newValue         }     } } The problem might be at line 243 (I found the struct DecimalTextField on the internet) Thank you for your time
2
0
1.6k
Dec ’20
Cannot convert value of type 'String' to type 'NSNumber' in coercion
Hello I'm trying to use a formatter on a String but it is giving me this error Cannot convert value of type 'String' to type 'NSNumber' in coercion, is there a simple and short way to fix it? Here is the code import SwiftUI struct TemperatureView: View { &#9;&#9; &#9;&#9;@State private var inputValue = "" &#9;&#9; &#9;&#9; let inputUnits = [ &#9;&#9;&#9;&#9;"celsius [°C]", &#9;&#9;&#9;&#9;"kelvin [K]", &#9;&#9;&#9;&#9;"fahrenheit [°F]" &#9;&#9;] &#9;&#9;let outputUnits = [ &#9;&#9;&#9;&#9;"celsius [°C]", &#9;&#9;&#9;&#9;"kelvin [K]", &#9;&#9;&#9;&#9;"fahrenheit [°F]" &#9; ] &#9;&#9;@State private var inputUnitValue = 0 &#9;&#9; &#9;&#9;@State private var outputUnitValue = 1 &#9;&#9; &#9;&#9; &#9;&#9;var after: String{ &#9;&#9;&#9;&#9;var input: Measurement<UnitTemperature> &#9;&#9;&#9;&#9;var output: String = "" &#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;switch inputUnits[inputUnitValue] { &#9;&#9;&#9;&#9;case "celsius [°C]": input = Measurement(value: Double(inputValue) ?? 0, unit: .celsius) &#9;&#9;&#9;&#9;case "kelvin [K]": input = Measurement(value: Double(inputValue) ?? 0, unit: .kelvin) &#9;&#9;&#9;&#9;case "fahrenheit [°F]": input = Measurement(value: Double(inputValue) ?? 0, unit: .fahrenheit) &#9;&#9;&#9;&#9;default: input = Measurement(value: Double(inputValue) ?? 0, unit: UnitTemperature.celsius) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;switch outputUnits[outputUnitValue] { &#9;&#9;&#9;&#9;case "celsius [°C]": output = outputFormatter.string(from: input.converted(to: .celsius)) &#9;&#9;&#9;&#9;case "kelvin [K]": output = outputFormatter.string(from: input.converted(to: .kelvin)) &#9;&#9;&#9;&#9;case "fahrenheit [°F]": output = outputFormatter.string(from: input.converted(to: .fahrenheit)) &#9;&#9;&#9;&#9;default: output = String(describing: input.converted(to: UnitTemperature.celsius)) &#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;return output &#9;&#9;} &#9;&#9; &#9;&#9;@Environment(\.presentationMode) var presentationMode &#9;&#9;let outputFormatter: MeasurementFormatter = { &#9;&#9;&#9;&#9;&#9;&#9;let nf = NumberFormatter() &#9;&#9;&#9;&#9;&#9;&#9;nf.locale = Locale.current &#9;&#9;&#9;&#9;&#9;&#9;nf.usesSignificantDigits = true &#9;&#9;&#9;&#9;&#9;&#9;let mf = MeasurementFormatter() &#9;&#9;&#9;&#9;&#9;&#9;mf.numberFormatter = nf &#9;&#9;&#9;&#9;&#9;&#9;mf.unitOptions = .providedUnit &#9;&#9;&#9;&#9;&#9;&#9;return mf &#9;&#9;&#9;&#9;}() &#9;&#9;&#9;&#9; &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;NavigationView{ &#9;&#9;&#9;&#9;&#9;&#9;Form{ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Section(header: Text("Enter your Input value")){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextField("Have a goal?", text: $inputValue) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.keyboardType(.decimalPad) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Section(header: Text("Input")){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Picker("Input values", selection: $inputUnitValue){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ForEach(0..<inputUnits.count){ item in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text(inputUnits[item]) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Section(header: Text("Output")){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Picker("Output values", selection: $outputUnitValue){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ForEach(0..<outputUnits.count){ item in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text(outputUnits[item]) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Section(header: Text("Check your Output value")){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text("\(after as NSNumber, formatter: outputFormatter)") &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;.navigationBarTitle("Temperature") &#9;&#9;&#9;&#9;&#9;&#9;.navigationBarItems(trailing: &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Button(action: { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;presentationMode.wrappedValue.dismiss() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;}) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Image(systemName: "xmark").font(.title).foregroundColor(.blue) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;) &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9; } The error is at line 80/81 Thank you for your time
1
0
3k
Jan ’21
Change background SwiftUI
Hello I made a custom Picker View but I don't have any idea on how to change the background color to grey when I press on one of the options Here is the code: struct PickerView: View { &#9;&#9; &#9;&#9;var arr: [String] = ["Easy", "Medium", "Hard"] &#9;&#9;var h: CGFloat = 50 &#9;&#9;var w: CGFloat = 320 &#9;&#9; &#9;&#9;@ObservedObject var input: UserInput &#9;&#9;var body: some View{ &#9;&#9;&#9;&#9;HStack(spacing: 40){ &#9;&#9;&#9;&#9;&#9;&#9;ForEach(0..<arr.count){ i in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;HStack(spacing: 25){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text(arr[i]) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.bold() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.onTapGesture { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;switch i{ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;case i: input.indi = i &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;default: return &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;print(i) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if(i < arr.count - 1){ &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Divider() &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.frame(height: 25) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;}.padding() &#9;&#9;&#9;&#9;.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous)) &#9;&#9;&#9;&#9;.overlay( &#9;&#9;&#9;&#9;&#9;&#9;RoundedRectangle(cornerRadius: 16) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;.stroke(Color.gray, lineWidth: 3) &#9;&#9;&#9;&#9;) &#9;&#9;} } class UserInput: ObservableObject { &#9;&#9;@Published var indi: Int = 0 } Thank you for your time
7
0
3.6k
Jan ’21
Touch and Face ID in SwiftUI
Hello Is there a way to know if the detected finger or face are wrong? I am using this function: func authenticate() { let context = LAContext() var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &amp;error) { let reason = "We need to unlock your data." context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError in DispatchQueue.main.async { if success { self.isUnlocked = true } else { userPressedCancel = false } } } } else { } }
1
0
940
Apr ’21
HealthKit (delete function in SwiftUI)
Hello I am trying to save some data in the Health App from my app, and it is working, the problem is that when I delete that data (already saved) from my app (using the deleteFromHealthKit function) the data is not deleted from the health app. How can I fix this? Here is the code: import SwiftUI import HealthKit struct ContentView: View { init() { //-------- let healthStore = HKHealthStore() let allTypes = Set([HKObjectType.quantityType(forIdentifier: .dietaryWater)!]) healthStore.requestAuthorization(toShare: allTypes, read: allTypes) { (success, error) in if !success { print("success") } } } func fetchHealthData(date: Date, ml: Double) -> Void { let healthStore = HKHealthStore() let quantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryWater) let waterConsumed = HKQuantitySample.init(type: quantityType!, quantity: .init(unit: HKUnit.literUnit(with: .milli), doubleValue: ml), start: date, end: date) healthStore.save(waterConsumed) { success, error in if (error != nil) { print("Error: \(String(describing: error))") } if success { print("Saved: \(success)") } } } @State var water: [Water] = [] @State private var value: Double = 0 func deleteFromHealthKit(date: Date, ml: Double) { let healthStore = HKHealthStore() let quantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryWater) let waterConsumed = HKQuantitySample.init(type: quantityType!, quantity: .init(unit: HKUnit.literUnit(with: .milli), doubleValue: ml), start: date, end: date) healthStore.delete(waterConsumed) { success, error in if (error != nil) { print("Error: \(String(describing: error))") } if success { print("Saved: \(success)") } } } var body: some View { NavigationView{ VStack{ Text("Value: \(value)") .padding() HStack{ Text("100 ml") .onTapGesture { value = 100 } Text("200 ml") .onTapGesture { value = 200 } } Button("Add"){ water.append(Water(value: value, date: Date())) fetchHealthData(date: Date(), ml: value) }.disabled(value == 0 ? true : false) .padding() List{ ForEach(0..<water.count, id: \.self){ i in HStack{ Text("\(water[i].value)") Text("\(water[i].date)") } .onTapGesture { deleteFromHealthKit(date: water[i].date, ml: water[i].value) water.remove(at: i) } } } } } } } struct Water: Identifiable { var id = UUID() var value: Double var date: Date } Thank you
2
0
1.6k
Jun ’21
Sync iCloud with different targets
Hello Is there a way to share data stored in CloudKit and CoreData between iOS and watchOS in SwiftUI? I am using the same CoreData file both, and I am using the same PersistenceController file both, and I am using the same CloudKit container for both. I tried adding the App Groups capability to all the targets, but it is not working. (I already enabled iCloud capability, Push notification capability and background Modes capability for both iOS and WatchOS)  PersistenceController: struct PersistenceController { static let shared = PersistenceController() static var preview: PersistenceController = { let result = PersistenceController(inMemory: true) let viewContext = result.container.viewContext do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } return result }() let container: NSPersistentCloudKitContainer init(inMemory: Bool = false) { container = NSPersistentCloudKitContainer(name: "Test7") if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") } container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy } } View: struct ContentView: View { @FetchRequest( entity: Item.entity(), sortDescriptors: [] ) var items: FetchedResults<Item> @Environment(\.managedObjectContext) private var context var body: some View { NavigationView{ List { ForEach(items) { item in Text("Item at \(item.date!)") } .onDelete(perform: deleteItems) } .toolbar { Button { addItem() } label: { Image(systemName: "plus") } } } } private func addItem() { withAnimation { let newItem = Item(context: context) newItem.date = Date() do { try context.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } private func deleteItems(offsets: IndexSet) { withAnimation { offsets.map { items[$0] }.forEach(context.delete) do { try context.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } } Thank you
0
0
641
Jun ’21
User Notifications in SwiftUI
Hello How can I set up local notifications that repeat every X minutes from a certain hour to another hour. For example, I want to receive a notification every 60 minutes starting from 12:00 AM to 10:00 PM? func scheduleNotifications() { let content = UNMutableNotificationContent() content.title = "App" content.subtitle = "App" content.sound = UNNotificationSound.default let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true) let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) } With this code I can schedule a notification every minute, however, I cannot decide from what time it should start or when it stops. Any ideas? Thank you!
0
0
1.3k
Jun ’21
onDelete not working properly in my app
Hello In my app I have a list of items in a ForEach and at the end of the ForEach there is a .onDelete. (This is in a View that I called AllHistoryView) The items are represented by a CoreData NSManagedObject that I called LifetimeInputs with 3 properties: date: Date, imageTemplate: String, valori: Double The problem is that, when I add (in a different View) an item with the date of tomorrow and then I add another to item with the date of today and then go to the AllHistoryView where there are all the items and delete slowly the item with date of tomorrow (especially at the end of the swipe action) instead of deleting the item that I swiped it deletes the on before it, how can I solve this problem? Here is the AllHistoryView code: import SwiftUI import CoreData struct AllHistoryView: View { @Environment(\.managedObjectContext) var viewContext @FetchRequest(entity: LifetimeInputs.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \LifetimeInputs.date, ascending: true)], animation: .default) var lifetimeInputsModel: FetchedResults<LifetimeInputs> @State private var text: String = "" @State private var ascending: Bool = true @State var sortDescriptor: NSSortDescriptor = NSSortDescriptor(keyPath: \LifetimeInputs.date, ascending: true) @Environment(\.dynamicTypeSize) var dynamicTypeSize var size: CGFloat{ if UIDevice.current.userInterfaceIdiom == .phone { switch dynamicTypeSize { case .xSmall: return 11 case .small: return 13 case .medium: return 15 case .large: return 17 case .xLarge: return 19 case .xxLarge: return 21 case .xxxLarge: return 23 default: return 23 } } else { switch dynamicTypeSize { case .xSmall: return 13 case .small: return 15 case .medium: return 17 case .large: return 19 case .xLarge: return 21 case .xxLarge: return 23 case .xxxLarge: return 25 case .accessibility1: return 27 case .accessibility2: return 29 default: return 29 } } } var body: some View { theView() } @ViewBuilder func theView() -> some View{ NavigationView{ if !lifetimeInputsModel.isEmpty{ List{ SectionList(sortDescripter: sortDescriptor, text: $text) .environment(\.managedObjectContext, viewContext) .onChange(of: ascending, perform: { _ in if ascending { withAnimation { sortDescriptor = NSSortDescriptor(keyPath: \LifetimeInputs.date, ascending: true) } } else { withAnimation { sortDescriptor = NSSortDescriptor(keyPath: \LifetimeInputs.date, ascending: false) } } }) } .searchable(text: $text, placement: .navigationBarDrawer, prompt: "Quantity or date".localized()) .navigationBarTitle("History", displayMode: .inline) .toolbar{ ToolbarItem(placement: .automatic) { Image(systemName: "arrow.up.arrow.down.circle") .foregroundColor(.primary) .font(.system(size: size)) .rotation3DEffect(.degrees(ascending ? 0 : 180), axis: (x: 1, y: 0, z: 0)) .opacity(0.5) .onTapGesture { ascending.toggle() } } } } else{ VStack{ Text("No Data".localized()) .font(.largeTitle) .fontWeight(.semibold) .foregroundColor(.secondary) } .padding(.bottom) .navigationBarTitle("History", displayMode: .inline) } } } } struct SectionList: View { @Environment(\.managedObjectContext) var viewContext @FetchRequest var lifetimeInputsModel: FetchedResults<LifetimeInputs> @Binding var text: String init(sortDescripter: NSSortDescriptor, text: Binding<String>) { let request: NSFetchRequest<LifetimeInputs> = LifetimeInputs.fetchRequest() request.sortDescriptors = [sortDescripter] _lifetimeInputsModel = FetchRequest<LifetimeInputs>(fetchRequest: request) self._text = text } @FetchRequest(entity: Limit.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Limit.date, ascending: true)], animation: .default) var limit: FetchedResults<Limit> @Environment(\.dynamicTypeSize) var dynamicTypeSize var size: CGFloat{ if UIDevice.current.userInterfaceIdiom == .phone { switch dynamicTypeSize { case .xSmall: return 11 case .small: return 13 case .medium: return 15 case .large: return 17 case .xLarge: return 19 case .xxLarge: return 21 case .xxxLarge: return 23 default: return 23 } } else { switch dynamicTypeSize { case .xSmall: return 13 case .small: return 15 case .medium: return 17 case .large: return 19 case .xLarge: return 21 case .xxLarge: return 23 case .xxxLarge: return 25 case .accessibility1: return 27 case .accessibility2: return 29 default: return 29 } } } @StateObject var lifeTimeInputsViewModel = LifeTimeInputsViewModel() var body: some View { Section{ ForEach(lifetimeInputsModel.filter { text.isEmpty || "\($0)".contains(text) }){ lifetimeInputs in HStack{ Text("\(lifetimeInputs.valori, specifier: format(unita: !limit.isEmpty ? limit[0].unita ?? ml : ml)) \(!limit.isEmpty ? limit[0].unita ?? ml: ml)") .font(.system(size: size)) Spacer() Text("\(dateFormatter.string(from: lifetimeInputs.date ?? Date()))") .font(.system(size: size)) } } .onDelete(perform: { offsets in lifeTimeInputsViewModel.deleteItems(offsets: offsets) }) } header: { Text("History".localized()).font(.system(size: size - 4)) } } } Thank You very much!
0
0
739
Sep ’21
Notify when @FetchRequest changes?
Hello @FetchRequest( entity: Book(), sortDescriptors: [] ) var books: FetchedResults<Book> How can I get notified when books changes? I was thinking about putting this... .onReceive(NotificationCenter.default.publisher(for: .NSManagedObjectContextDidSave), perform: { _ in}) ... in my main View but this would notify me if anything gets saved and that is not what I want. I want to get notified just if a certain FetchRequest changes (in this case books)? And in another thread I was told to use... .onRecevie(books.publisher){ _ in .... } ...however using this code publishes each member of the sequence as a separate element, I want it to publish just once? Thank You!
0
0
570
Sep ’21
@propertywrapper in SwiftUI
Hello I created a @propertyWrapper to limit the number a variable can reach. I tried it in a SwiftUI view with a button that increases the value of the variable and it works, the variable stops at the maximum number set in the initializer. However if I try it with a Textflied it doesn't work, if I insert a higher number than the one set nothing happens, it makes me do it. How can I solve this problem, I know the problem has to do with Binding but I don't know exactly what it is, here is the code: import SwiftUI struct ContentView: View { @Maximum(maximum: 12) var quantity: Int var body: some View { NavigationView{ Form{ TextField("", value: $quantity, format: .number, prompt: Text("Pizza").foregroundColor(.red)) Button { quantity += 1 } label: { Text("\(quantity)") } } } } } @propertyWrapper struct Maximum<T: Comparable> where T: Numeric { @State private var number: T = 0 var max: T var wrappedValue: T { get { number } nonmutating set { number = min(newValue, max) } } var projectedValue: Binding<T> { Binding( get: { wrappedValue }, set: { wrappedValue = $0 } ) } init(maximum: T){ max = maximum } } extension Maximum: DynamicProperty { } Thank You for your time
0
0
954
Dec ’21