Hello
Do you know why the comma in this calculator app isn't working:
import SwiftUI
import Combine
enum Nums: String{
case uno = "1"
case due = "2"
case tre = "3"
case quattro = "4"
case cinque = "5"
case sei = "6"
case sette = "7"
case otto = "8"
case nove = "9"
case zero = "0"
case moltiplicazione = "X"
case divisione = "/"
case somma = "+"
case meno = "-"
case uguale = "="
case AC = "AC"
case piùMeno = "±"
case percentuale = "%"
case virgola = "."
case niente = ""
}
struct ContentView: View {
var numeri: [[Nums]] = [
[Nums.AC, Nums.piùMeno, Nums.percentuale, Nums.divisione],
[Nums.sette, Nums.otto, Nums.nove, Nums.moltiplicazione],
[Nums.quattro, Nums.cinque, Nums.sei, Nums.meno],
[Nums.uno, Nums.due, Nums.tre, Nums.somma],
[Nums.zero, Nums.niente, Nums.virgola, Nums.uguale]
]
private var gridItemLayout = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]
@State var previousVar: Double = 0
let timer = Timer.publish(every: 0.001, on: .main, in: .common).autoconnect()
@State var con: Int = 0
@State var final: Double = 0
@State var operat = Nums(rawValue: "")
@State var digits: String = "0"
var res: Double {
get {
//digits.hasSuffix(".") ? Double(digits.dropLast()) ?? 0.0 : Double(digits) ?? 0.0
digits.hasSuffix(".") ? Double(digits) ?? 0.0 : Double(digits) ?? 0.0
}
nonmutating set {
digits = String(format: "%.10g", newValue) //- May need better formatting
}
}
var body: some View {
VStack{
Spacer()
HStack{
Spacer()
Text("\(digits)")
.font(.system(size: 50))
.bold()
.padding()
}
Spacer()
LazyVGrid(columns: gridItemLayout, content: {
ForEach(0..5){ i in
ForEach(0..4){ j in
RoundedRectangle(cornerRadius: 35.0)
.foregroundColor(.orange)
.frame(width: 80, height: 80, alignment: .center)
.overlay(
Text("\(numeri[i][j].rawValue)")
.font(.largeTitle)
.foregroundColor(.black)
).onTapGesture {
switch numeri[i][j] {
case Nums.AC:
operat = Nums.AC;
res = 0
case Nums.uguale:
operat = Nums.uguale;
res = final
case Nums.somma:
operat = Nums.somma;
previousVar = res;
res = 0;
con = 0
case Nums.meno:
operat = Nums.meno;
previousVar = res;
res = 0
con = 0
case Nums.divisione:
operat = Nums.divisione;
previousVar = res;
res = 0;
con = 0
case Nums.moltiplicazione:
operat = Nums.moltiplicazione;
previousVar = res;
res = 0;
con = 0
case Nums.percentuale:
operat = Nums.percentuale;
res = res / 100
case Nums.piùMeno:
operat = Nums.piùMeno;
if digits.hasPrefix("-") {
digits = String(digits.dropFirst())
} else {
digits = "-" + digits
}
con = 0
case Nums.virgola:
operat = Nums.virgola;
if !digits.contains(".") {
digits += "."
}
default:
if digits == "0" {
digits = numeri[i][j].rawValue
} else {
digits += numeri[i][j].rawValue
}
con += 1
}
}
}
}
}).onReceive(timer) { _ in
if con != 0 {
if operat == Nums.divisione{
final = previousVar / res
} else if operat == Nums.meno{
final = previousVar - res
} else if operat == Nums.moltiplicazione{
final = previousVar * res
} else if operat == Nums.somma{
final = previousVar + res
}
}
}
}.padding(2)
}
}
Maybe at line 51 and 52 or 121
(If you can explain my mistakes all around the code I would be grateful)
Thank you
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello
I am getting a lot of errors in ForEach and I don't know why at all.
Here is the code:
The error is at line 12
import SwiftUI
import Combine
struct ContentView: View {
@EnvironmentObject var networkController: NetworkControllerItalia
var body: some View {
Form{
TextField("Input city name", text: $networkController.cityName)
Section {
ForEach(networkController.users.weather, id: \.self){ user in
}
}
}
}
}
class NetworkControllerItalia: ObservableObject {
private var can: AnyCancellable?
@Published var cityName: String = ""
@Published var users = [UserItalia(weather: Weather())]
init(cityName: String) {
self.cityName = cityName
let url = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=\(cityName)&appid=")!
self.can = URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: [UserItalia].self, decoder: JSONDecoder())
.eraseToAnyPublisher()
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {completion in
print(completion)
}, receiveValue: { users in
self.users = users
})
}
}
struct UserItalia: Decodable, Hashable{
var weather: Weather
}
struct Weather: Decodable, Hashable {
var main: String?
}
Thank you
Hello
I get errors in ForEach that I don't know how to solve:
Generic struct 'ForEach' requires that 'Main' conform to 'RandomAccessCollection'
Unable to infer type of a closure parameter 'user' in the current context
Error at line 30 - 31
Code:
//
// ContentView.swift
// ARWeather
//
// Created by Jad Taljabini on 08/04/21.
//
import SwiftUI
import Combine
struct ContentView: View {
@EnvironmentObject var networkController: NetworkControllerItalia
var body: some View {
NavigationView {
Form{
TextField("Input city name", text: $networkController.cityName, onEditingChanged: { te_xt in
networkController.url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(networkController.cityName)&appid=") ?? URL(string: "https://www.apple.com")!
networkController.fun()
}, onCommit: {
withAnimation{
networkController.url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(networkController.cityName)&appid=") ?? URL(string: "https://www.apple.com")!
networkController.fun()
}
})
Section {
ForEach(networkController.users.weather ?? [], id: \.self){ user in
Text(user.main ?? "")
}
ForEach(networkController.users.main ?? Main(temp: 0), id: \.self){ user in
Text("\(user.temp)")
}
}
}
}
}
}
class NetworkControllerItalia: ObservableObject {
private var can: AnyCancellable?
@Published var cityName: String = ""
@Published var users = UserItalia(weather: [])
var url = URL(string: "https://www.apple.com")!
func fun(){
self.can = URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: UserItalia.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: {completion in
print(completion)
}, receiveValue: { users in
self.users = users
})
}//Funzione che riempe users di dati da internet
}
struct UserItalia: Decodable, Hashable{
var weather: [Weather]?
var main: Main?
}
struct Weather: Decodable, Hashable {
var main: String?
}
struct Main: Decodable, Hashable {
var temp: Float
}
The JSON API is like this:
{
"coord": {
"lon": -0.1257,
"lat": 51.5085
},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"base": "stations",
"main": {
"temp": 285.45,
"feels_like": 283.96,
"temp_min": 284.82,
"temp_max": 285.93,
"pressure": 1021,
"humidity": 47
},
"visibility": 10000,
"wind": {
"speed": 5.66,
"deg": 220
},
"clouds": {
"all": 20
},
"dt": 1617888145,
"sys": {
"type": 1,
"id": 1414,
"country": "GB",
"sunrise": 1617859180,
"sunset": 1617907473
},
"timezone": 3600,
"id": 2643743,
"name": "London",
"cod": 200
}
Thank you
Hello
Why does it give me an error when I pass 'name' at line 3?
struct OtherView: View {
@State private var name: String = ""
@ObservedObject var use = Use(name: name)
var body: some View{
VStack{
}
}
}
class Use: ObservableObject {
@Published var name: String
init(name: String) {
self.name = name
}
}
Thank you
Hello
I have a Raindrop shape:
struct Raindrop: Shape {
func path(in rect: CGRect) - Path {
Path { path in
path.move(to: CGPoint(x: rect.size.width / 2, y: 0))
path.addQuadCurve(to: CGPoint(x: rect.size.width / 2, y: rect.size.height), control: CGPoint(x: rect.size.width, y: rect.size.height))
path.addQuadCurve(to: CGPoint(x: rect.size.width / 2, y: 0), control: CGPoint(x: 0, y: rect.size.height))
}
}
}
When I trim it in the ContentView, it trims from right to left, is there a way to trim it from top to bottom?
Raindrop()
.trim(from: 0.9, to: 1)
.scaledToFit()
Thank you
Hello
import SwiftUI
enum When: String {
case Today
case Week
case Month
case Year
}
struct ChartView: View {
var when: When
@EnvironmentObject var millilitriInseritiModel: MillilitriInseritiModel
var valoriAsseX: [String]{
if when == When.Week{
return ["M", "T", "W", "T", "F", "S", "S"]
} else if when == When.Month{
return ["7", "14", "21", "28"]
} else if when == When.Year{
return ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]
}
return []
}
var valoriAsseY: [Double]{
return []
}
var dates: [Date] = [Date(), Date().addingTimeInterval(86400), Date().addingTimeInterval(86400 * 2)]
@State var valori: [Double] = [1000, 2000, 3000, 1000, 2000, 1000, 2000, 3000, 1000, 2000, 3000]
var altezzaRettangolo: [Double]?{
var altezze: [Double] = []
for i in 0..<valori.count{
altezze.append(valori[i])
}
return altezze
}
@State var animation: Bool = false
var body: some View{
HStack(alignment: .bottom, spacing: 8, content: {
ForEach(valoriAsseX.indices){ i in
VStack{
RoundedRectangle(cornerRadius: 3)
.fill(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .top, endPoint: .bottom))
.frame(width: 40, height: animation ? CGFloat(altezzaRettangolo?[i] ?? 0) / 7 : 0)
.animation(.easeInOut)
Text(valoriAsseX[i])
.fontWeight(.semibold)
.multilineTextAlignment(.leading)
.onTapGesture {
withAnimation{
valori[i] += 100
}
}
}
}
})
.padding()
.onAppear {
animation = true
}
.onDisappear {
animation = false
}
}
}
struct ChartView_Previews: PreviewProvider {
static var previews: some View {
ChartView(when: When.Year)
}
}
As you might notice, in the previews I set when to When.Year, that is crashing the app because the array valoriAsseX is bigger than the array altezzaRettangolo, so when I iterate it in the ForEach loop it crashes, I can't find any way to solve this, I tried an if let but it is crashing anyway, any ideas?
Thank you
Hello
I implemented the filter function in my ForEach loop, and it works just with the valori property but not with the date property , is there a way to let it filter also the date?
I tried to remove the dateFormatter but it didn't work.
Here is the code
import SwiftUI
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
return formatter
}()
struct Test4: View {
@State private var text: String = ""
var body: some View {
NavigationView{
if !lifetimes.isEmpty{
List{
Section(header: Text("")){
TextField("Search", text: $text)
}
Section(header: Text("")){
ForEach(lifetimes.filter { text.isEmpty || "\($0)".contains(text) }, id: \.id){ lifetimeInputs in
HStack{
Text("\(lifetimeInputs.valori, specifier: "%.0f")")
Spacer()
Text("\(dateFormatter.string(from: lifetimeInputs.date))")
}
}
}
}
.listStyle(InsetGroupedListStyle())
.navigationTitle("All History")
} else{
VStack{
Text("No Data")
.font(.largeTitle)
.fontWeight(.semibold)
.foregroundColor(.secondary)
}
.padding(.bottom)
.navigationTitle("All History")
}
}
}
}
struct LifetimeInputsModel: Identifiable {
var id = UUID()
var valori: Double
var date: Date
}
var lifetimes: [LifetimeInputsModel] = [
LifetimeInputsModel(valori: 300, date: Date()),
LifetimeInputsModel(valori: 200, date: Date() + 86400)
]
Thank you
Hello
I am developing an app with SwiftUI using CoreData and iCloudKit to sync data between platforms.
The problem is that the iCloud background update is not being triggered when staying in the application. If I make changes on both systems, the changes are being pushed, however not visible on the other device.
I need to reload the app, close the app and open again.
I already enabled iCloud capability, background notifications and push notifications.
This is my persistentContainer
var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "Test7")
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
return container
}()
func saveContext() {
let context = persistentContainer.viewContext
if context.hasChanges{
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
This is my model
class ItemsModel: ObservableObject {
init() {
readData()
}
@Published var dataInputs: [Item] = []
let context = persistentContainer.viewContext
func readData(){
let request: NSFetchRequest<Item> = Item.fetchRequest()
do {
let results = try context.fetch(request)
self.dataInputs = results
} catch {
print(error.localizedDescription)
}
}
func addItem(todo: String, date: Date){
let entity = NSEntityDescription.insertNewObject(forEntityName: "Item", into: context) as! Item
entity.todo = todo
entity.date = date
do {
try context.save()
self.dataInputs.append(entity)
} catch {
print(error.localizedDescription)
}
}
func deleteItems(indexSet: IndexSet){
for index in indexSet{
do {
let obj = dataInputs[index]
context.delete(obj)
try context.save()
let index = dataInputs.firstIndex(of: obj)
dataInputs.remove(at: index!)
} catch {
print(error.localizedDescription)
}
}
}
}
and this is my view
struct ContentView: View {
@EnvironmentObject var items: ItemsModel
var body: some View {
NavigationView{
List {
ForEach(items.dataInputs) { item in
Text("Item at \(item.date!)")
}
.onDelete(perform: items.deleteItems)
}
.toolbar {
Button {
items.addItem(todo: "Hello", date: Date())
} label: {
Image(systemName: "plus")
}
}
}
}
}
Thank you
Hello
Is there way to keep calling a function (efficiently) while the view is on screen, without using a timer, in SwiftUI?
Hello
I am making a counter app using Core Data to store the value that the user has reached, the problem is that in the DetailView the value changes just if I close the view and reopen it, how can I change the value immediately when the user taps the button?
ContentView:
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.date, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
@State private var isShown: Bool = false
var body: some View {
NavigationView{
List {
Section(header: Text("All counters")){
ForEach(items) { item in
NavigationLink(
destination:
DetailView(item: item)
.environment(\.managedObjectContext, viewContext)
,
label: {
HStack{
Text(item.name ?? "")
.font(.title3)
.fontWeight(.semibold)
Spacer()
Text("\(item.value, specifier: "%.0f")")
.font(.title3)
.fontWeight(.semibold)
}
})
}
.onDelete(perform: { indexSet in
deleteItems(offsets: indexSet)
print(items)
})
}
}
.listStyle(InsetGroupedListStyle())
.sheet(isPresented: $isShown, content: {
AddView()
.environment(\.managedObjectContext, viewContext)
})
.navigationBarTitle("Counter")
.toolbar {
Menu {
Button(action: {
isShown.toggle()
}) {
Text("Add Item")
}
EditButton()
} label: {
Image(systemName: "plus")
.font(.title)
}
}
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
}
}
}
DetailView:
struct DetailView: View {
@Environment(\.managedObjectContext) private var viewContext
var item: Item
var body: some View {
VStack(alignment: .center, spacing: nil, content: {
Text("\(item.value, specifier: "%.0f")")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.top)
Spacer()
HStack{
Button(action: {
withAnimation{
item.value += 1
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
}
}, label: {
Image(systemName: "plus")
})
Button(action: {
withAnimation{
item.value -= 1
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
}
}, label: {
Image(systemName: "minus")
})
}
.foregroundColor(.primary)
Spacer()
})
.navigationBarTitle(item.name ?? "", displayMode: .inline)
}
}
Thank you
Hello
I noticed that in my app, when I add data (I am using Core Data) the size of the app increases, as expected, the problem occurs when I delete data, the size of the app remains unchanged and sometimes increases, I thought there was an error in the my code and so I created, from scratch, a project for iOS with SwiftUI and Core Data enabled (the default template that Xcode provides) and also with the SwiftUI & Core Data default app the same problem happens.
Is there a way to fix it or is there an explanation for this?
Thank you!
Hello
I am using matched Geometry Effect to make animations and transitions, the problem is that when I press to start the animation, the object being animated, in this case Text, is duplicated during the transition, and then when I press again to get it back to its original position, no animation takes place, how can I fix it.
Here is the code:
struct ContentView: View {
@StateObject var numberViewModel = NumberViewModel()
@Namespace var animation
var body: some View {
GeometryReader { geo in
NavigationView{
ZStack {
ScrollView{
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) {
ForEach(numbers){ number in
NumberView(numberViewModel: numberViewModel, animation: animation, number: number)
.onTapGesture {
withAnimation(.easeInOut(duration: 1)){
numberViewModel.selected = number
numberViewModel.tapped = true
}
}
}
}
}
if numberViewModel.tapped{
NumberTappedView(animation: animation, numberViewModel: numberViewModel)
.position(
x: geo.frame(in:.global).midX,
y: geo.frame(in:.global).midY
)
.onTapGesture {
withAnimation(.easeInOut(duration: 1)){
numberViewModel.selected = Number(number: 0)
numberViewModel.tapped = false
}
}
}
}
}
}
}
}
struct NumberView: View {
@ObservedObject var numberViewModel: NumberViewModel
var animation: Namespace.ID
var number: Number
var body: some View{
GroupBox{
if !(numberViewModel.selected.number == number.number){
Text("\(number.number)")
.font(.largeTitle)
.frame(width: 100, height: 100, alignment: .center)
.matchedGeometryEffect(id: number.number, in: animation)
}
}
}
}
struct Number: Identifiable {
var id = UUID()
var number: Int
}
var numbers: [Number] = [
Number(number: 1),
Number(number: 2)
]
struct NumberTappedView: View {
var animation: Namespace.ID
@ObservedObject var numberViewModel: NumberViewModel
var body: some View{
GroupBox{
Text("\(numberViewModel.selected.number)")
.font(.largeTitle)
.frame(width: 200, height: 200, alignment: .center)
.matchedGeometryEffect(id: numberViewModel.selected.number, in: animation)
}
}
}
class NumberViewModel: ObservableObject {
@Published var selected: Number = Number(number: 0)
@Published var tapped: Bool = false
}
Thank You!
Hello
I was trying to use @FetchRequest in a class, but found it doesn't work, so I was wondering if there was a way to use something that works like @FetchRequest in a class?
Thank You!
Hello
I wanted to know why when I print(Date()) the date is printed but two hours before?
Example
If I print(Date()) and the actual date is 2021-09-10 22:33:41 +0000, it prints 2021-09-10 20:33:41 +0000 instead of 2021-09-10 22:33:41 +0000.
Why does this happen?
Thank You!
Hello
I created a custom shape in SwiftUI and I am trying to rotate it around a circle, but it works just on the top part of the circle, can you help me make it rotate exactly around the circle?
(And also can I get the same effect using radians? How?)
Here is the code:
import SwiftUI
struct MyGameView: View {
@State private var degress: Double = 0
let timer = Timer.publish(every: 0.05, on: .main, in: .common).autoconnect()
var body: some View {
VStack{
ZStack{
Circle()
.frame(width: 80)
ZStack{
Circle()
.stroke(lineWidth: 1)
.frame(width: 300)
BallonShape()
.scaledToFit()
.scaleEffect(0.2)
.foregroundColor(.red)
.rotationEffect(.degrees(degress), anchor: .bottom)
.offset(x: 0, y: -170)
}
}
}
.onReceive(timer) { input in
withAnimation(.easeIn(duration: 0.05).speed(10)){
degress += 1
}
}
}
}
struct BallonShape: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
path.move(to: CGPoint(x: rect.midX, y: (rect.maxY + rect.midY) / 2))
path.addCurve(to: CGPoint(x: rect.midX, y: rect.minY), control1: CGPoint(x: (rect.midX + rect.minX) / 2, y: rect.minY), control2: CGPoint(x: (rect.midX + rect.minX) / 2, y: rect.minY))
path.addCurve(to: CGPoint(x: rect.midX, y: (rect.maxY + rect.midY) / 2), control1: CGPoint(x: (rect.midX + rect.maxX) / 2, y: rect.minY), control2: CGPoint(x: (rect.midX + rect.maxX) / 2, y: rect.minY))
}
}
}
Thank You very much!