Post not yet marked as solved
I have a view that I am trying to get to animate on state change either using a transition or animate and so far nothing I've done has worked.
I've tried using withAnimation and .transition in various manners and no luck. Below is a repro and you'll see that the transition is very jagged.
Looking for suggestions on the best approach.
struct StackView: View {
@State var showStack = true
let columns = [
GridItem(.flexible()),
GridItem(.flexible()),
]
var body: some View {
VStack {
if showStack {
ZStack {
ForEach(0 ..< 15) { item in
TileView()
.rotationEffect(.degrees(Double.random(in: 1..<45)))
.transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .bottom)))
}
}
} else {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(0 ..< 15) { item in
TileView()
.transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .bottom)))
}
}
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.9) {
withAnimation(Animation.easeInOut(duration: 1).delay(0.5)) {
showStack = false
}
}
}
}
}
struct TileView: View {
var body: some View {
RoundedRectangle(cornerRadius: 13)
.frame(width: 175, height: 175, alignment: .center)
.foregroundColor(.red)
.shadow(radius: 13)
.overlay(
Text("1")
.font(.largeTitle)
)
.transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .bottom)))
}
}
Post not yet marked as solved
I have pretty basic function for testing purposes to save a text file to File.app, but the created text file does not ever appear in the File.app.
func saveDocToFiles() {
let file = "DummyFile.txt"
let contents = "some text"
let resourceDocPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! //replace with if let
let fileURL = resourceDocPath.appendingPathComponent(file)
do {
try contents.write(to: fileURL, atomically: true, encoding: .utf8)
print("successfully saved - document library \(self.getDocumentsDirectory())")
} catch {
print("oh no could not be saved")
}
}
I've added both keys below:
Application supports iTunes file sharing
Supports opening documents in place
While using a simulator if I browse to the document library the file is created. I've tested this on an actual device and the behavior is the same.
Am I missing a configuration for the file to appear in File.app?
Post not yet marked as solved
I'm getting back the following error when attempting to call data for VA facility information.
failure(Swift.DecodingError.valueNotFound(
Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil),
CodingKeys(stringValue: "attributes", intValue: nil),
CodingKeys(stringValue: "wait_times", intValue: nil),
CodingKeys(stringValue: "health", intValue: nil), _JSONKey(stringValue: "Index 6", intValue: 6),
CodingKeys(stringValue: "new", intValue: nil)], debugDescription: "Expected Double value but found null instead.", underlyingError: nil)))
I check with Postman and the data is present so I'm not entirely sure why the data is failing.
Here's part of my model
// MARK: - Welcome
struct Welcome: Codable, Identifiable {
let id = UUID()
let data: DataClass
}
// MARK: - DataClass
struct DataClass: Codable {
let id, type: String
let attributes: Attributes
}
// MARK: - Attributes
struct Attributes: Codable {
let name, facilityType, classification: String
let website: String
let lat, long: Double
let timeZone: String
let address: Address
let phone: Phone
let hours: Hours
let operationalHoursSpecialInstructions: String
let services: Services
let satisfaction: Satisfaction
let waitTimes: WaitTimes
let mobile: Bool
let activeStatus: String
let operatingStatus: OperatingStatus
let detailedServices: [DetailedService]
let visn: String
enum CodingKeys: String, CodingKey {
case name
case facilityType = "facility_type"
case classification, website, lat, long
case timeZone = "time_zone"
case address, phone, hours
case operationalHoursSpecialInstructions = "operational_hours_special_instructions"
case services, satisfaction
case waitTimes = "wait_times"
case mobile
case activeStatus = "active_status"
case operatingStatus = "operating_status"
case detailedServices = "detailed_services"
case visn
}
}
Here's my function call
typealias vaFacilityData = [Welcome]
Class .... {
@Published var vaFacilityData: [Welcome] = []
func getVAFacilityInfo(locationURL: String) {
var URLBuilder = URLComponents(string: locationURL)
guard let url = URLBuilder?.url else { return }
var request = URLRequest(url: url)
// request.httpMethod = "GET"
request.setValue(VA_API_Key, forHTTPHeaderField: "apikey")
print("\(#function) url \(locationURL)")
URLSession.shared.dataTaskPublisher(for: request)
.subscribe(on: DispatchQueue.global(qos: .background))
.receive(on: DispatchQueue.main)
.tryMap { (data, response) -> Data in
guard
let response = response as? HTTPURLResponse,
response.statusCode >= 200 && response.statusCode < 300 else {
self.appError = AppError(errorString: "\(UserFetchError.badServerResponse)")
throw UserFetchError.badServerResponse
}
print("\(#function) response \(response.statusCode)")
print("\(#function) returning data \(data)")
return data
}
.decode(type: Welcome.self, decoder: JSONDecoder())
.sink { (completion) in
print("\(#function) completion - \(completion)")
} receiveValue: { (returnedData) in
print("\(#function) returnedData - \(returnedData)")
self.vaFacilityData = [returnedData]
}
.store(in: &cancellabes)
}
}
}
So not sure what I'm doing wrong here with userDefaults and my array. I'm only seeing the last Int and nothing else added before.
func addItem(completedTask: Int){
var array: [Int] = []
array.append(completedTask)
// Setting userDefaults
let userDefaults = UserDefaults.standard
userDefaults.set(array, forKey: "userDefault-completedItems")
// Read userDefaults
let userDefaultArray = userDefaults.array(forKey: "userDefault-completedItems") as? [Int] ?? [Int]()
print("added items read from userdefaults \(userDefaultArray)")
for item in userDefaultArray {
print(item)
}
}
Post not yet marked as solved
The simulator is on the left and preview on the right. Not sure why the padding is completely removed.
Here's my code:
GeometryReader { graph in
VStack {
ZStack {
Color("Background")
.cornerRadius(23)
.shadow(color: Color("Shadow").opacity(0.3), radius: 4)
VStack {
Text("Program Completion")
.bold()
ProgressViewCircle(progress: $progressValue)
.frame(width: 150.0, height: 150.0)
}
}
.frame(width: graph.size.width - 30, height: graph.size.height / 3 )
.padding()
}
}
My view is called, but the default data is being used. My class is set like so
class UserWeatherData: ObservableObject {
@Published var currentDescription = "It's gonna rain!"
}
My view:
struct WeatherView: View {
@AppStorage("userTempChoice") var userTempChoice = "Fahrenheit"
@ObservedObject var weather = UserWeatherData()
var body: some View {
VStack {
Text("Tap Me")
.onTapGesture {
I set my data
}
}
}
}
Here is where things are not working for me and weather.currentDescription is using the default data set above and not what I set.
struct SampleWeatherView: View {
@StateObject var weather = UserWeatherData()
var body: some View {
Text(weather.currentDescription)
}
}
Post not yet marked as solved
I have two API call's for data and if openWeatherData fails it prevents planData.trainingdata from loading. Is there a way to workaround this so planData still loads?
List(planData.trainingdata) { index in
ForEach(openWeatherData.openWeatherData) { day in
...
}
}
Here's the API call for openWeather
class DownloadOpenWeatherData: ObservableObject {
@Published var openWeatherData: [OpenWeatherDecoder] = []
let locationManager = LocationManager()
var openWeatherCancellabes = Set<AnyCancellable>()
init() {
print("OpenWeather: loading init")
locationManager.startLoc()
getOpenWeatherData(weatherUrl: "https://api.openweathermap.org/data/2.5/onecall?lat=\(locationManager.getLat())&lon=\(locationManager.getLong())&exclude=hourly,minutely&appid")
locationManager.stopLoc()
}
func getOpenWeatherData(weatherUrl: String) {
guard let weatherUrl = URL(string: weatherUrl) else { return }
print("getOpenWeather url \(weatherUrl)")
URLSession.shared.dataTaskPublisher(for: weatherUrl)
.subscribe(on: DispatchQueue.global(qos: .background))
.receive(on: DispatchQueue.main)
.tryMap { (data, response) -> Data in
print(response)
guard
let response = response as? HTTPURLResponse,
response.statusCode >= 200 && response.statusCode < 300 else {
throw URLError(.badServerResponse)
}
print("data \(data)")
return data
}
.decode(type: OpenWeatherDecoder.self, decoder: JSONDecoder())
.sink { (completion) in
print(completion)
} receiveValue: { (returnedWeatherData) in
self.openWeatherData = [returnedWeatherData]
print("returnedWeatherData \(returnedWeatherData)")
}
.store(in: &openWeatherCancellabes)
}
}
I'm racking my head here trying to figure out the best way to do this, but I have two arrays. One array is a range of dates and another is a return of data.
Here's the function that returns an array of dates
func numberOfDaysBetween(startDate: Date, raceDate: Date) -> [Date] {
let numberOfDays = Calendar.current.dateComponents([.day], from: startDate, to: raceDate).day!
let week = (-numberOfDays...0).compactMap {
Calendar.current.date(byAdding: .day, value: $0, to: raceDate)
}
return week
}
I'm trying to get the dates to align to the weekdays listed here. https://api.npoint.io/6a55ea69409d7f3d90b4.
Would a ZStack be appropriate here?
Post not yet marked as solved
Here's the model of the API that I'm using
// MARK: - Welcome
struct NOAAWeatherDecoder: Codable, Identifiable {
var id = UUID()
let type: String
let geometry: Geometry
let properties: Properties
enum CodingKeys: String, CodingKey {
case type, geometry, properties
}
}
// MARK: - Properties
struct Properties: Codable {
let updated: Date
let units, forecastGenerator: String
let generatedAt, updateTime: Date
let validTimes: String
let elevation: Elevation
let periods: [Period]
}
// MARK: - Elevation
struct Elevation: Codable {
let value: Double
let unitCode: String
}
// MARK: - Period
struct Period: Codable {
let number: Int
let name: String
let startTime, endTime: Date
let isDaytime: Bool
let temperature: Int
let temperatureUnit: TemperatureUnit
let temperatureTrend: JSONNull?
let windSpeed, windDirection: String
let icon: String
let shortForecast, detailedForecast: String
}
I am able to get upto periods, but nothing after that. Here's the part of the code where I'm running into the issue
ForEach(noaaWeatherData.weathernoaadata) { day in Text(day.properties.periods[0]) After this I'm not entirely sure. }
Thanks!
Post not yet marked as solved
I have two views where I'm trying to get View 2 to run the function in the Observable object and\or update an array so far I've not been able to get it to run or update the array. I'm still learning how to work with ObservableObjects. Thanks!
View1.swift:
@Published var arrayInt = [6, 6.5]
@Published var fooString = "Name"
func appendToArray() {
fooString = "Boom, updated!"
arrayInt.append(11)
}
}
struct GraphView: View {
@StateObject var graph = graphData()
var body: some View {
.... some data
}
}
View2.swift:
struct DetailView: View {
@StateObject var graph = graphData()
var body: some View {
....Some data
.onAppear{
graph.appendToArray()
graph.arrayInt.append(11)
}
}
}
Post not yet marked as solved
I have a userDefault using Appstorage and would like to have a function access that value to use in a switch. What would be the best approach to accomplish this?
Post not yet marked as solved
I'm using Xcode 11.7 and my app is targeted for 13.1 and when changing the State of a property in quick succession the app is crashing to a black screen and then returns to the lock screen.
I'm not getting any crash report on the device and when I hook it up to Xcode I just get the following errors:
2020-09-15 06:42:28.586026-0400 [26842:7830878] XPC connection interrupted
2020-09-15 06:42:28.589083-0400 [26842:7831204] [ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke
I'm not really sure how to troubleshoot this.
Post not yet marked as solved
I'm running into an issue where I'm trying to do two things
Uncheck an existing checkbox when another one is checked. Basically only allow for one state to be active.
When I have one boxed checked every box is showing checked when the pages appears as a sheet.
Here's a repro of what i'm working on.
struct Themes: View {
var body: some View {
List {
ForEach (themeData) { themedata in
ThemesView(themedata: themedata)
}
.padding()
}
}
}
struct ThemesView: View {
var themedata: themes
@State var themedCheck = UserDefaults.standard.bool(forKey: "ThemeChecked")
@State var themeColorUserSetting = UserDefaults.standard.string(forKey: "ThemeColor")
@State var themeColor = "card3"
var body: some View {
HStack(spacing: 16) {
Circle()
.fill(Color(themedata.color))
.frame(width: 25, height: 25, alignment: .center)
Text(themedata.name)
.font(.custom("ProximaNova-Regular", size: 18))
Text("\(self.themeColor)")
Spacer()
ZStack {
RoundedRectangle(cornerRadius: 7)
.stroke(style: StrokeStyle(lineWidth: 1.5))
.frame(width: 35, height: 35)
.foregroundColor(themedCheck ? Color("card2") : Color.gray.opacity(0.2))
RoundedRectangle(cornerRadius: 7)
.trim(from: 0, to: 1)
.fill(themedCheck ? Color("card2") : Color.gray.opacity(0.2))
.frame(width: 25, height: 25)
if themedCheck {
Image(systemName: "checkmark")
.foregroundColor(Color.white)
}
}
.onTapGesture{
if !self.themedCheck {
withAnimation(Animation.easeIn(duration: 0.5)) {
self.themedCheck.toggle()
UserDefaults.standard.set(self.themedCheck, forKey: "ThemeChecked")
UserDefaults.standard.set(self.themeColorUserSetting, forKey: "ThemeColor")
self.themeColor = themedata.color
}
} else {
withAnimation{
self.themedCheck.toggle()
UserDefaults.standard.set(self.themedCheck, forKey: "ThemeChecked")
self.themeColor = "card3"
}
}
}
}
}
}
struct themes: Identifiable {
var id = UUID()
var name: String
var color: String
}
let themeData = [
themes(name: "Default", color: "card3"),
themes(name: "Theme 1", color: "Theme1"),
themes(name: "Theme 2", color: "Theme2")
]
Post not yet marked as solved
I know about .onDelete modifier, but say I want to remove an item from Coredata using onTapGesture is that possible?
.onDelete { indexSet in
let deleteItem = self.isFavorite[indexSet.first!]
self.managedObjectContext.delete(deleteItem)
do {
try self.managedObjectContext.save()
}catch {
print(error)
}
}
I tried doing
.onTapGesture { indexSet in
let deleteItem = self.isFavorite[indexSet.first!]
self.managedObjectContext.delete(deleteItem)
do {
try self.managedObjectContext.save()
}catch {
print(error)
}
}
But that didn't go well.
Post not yet marked as solved
I found in the latest update of iOS and xCode that onTapGesture isn't consistently registering onTap. Here's a stripped down version of the code I'm using that reproduces this issue. In this case onTap for safari is not working.
I don't reproduce this with iOS13 or if I'm using onLongPress
Has anyone else experienced this in the latest update?
@State var runclubs: [RunClubsv2] = []
//Search filter
@State var showSearch = false
@State private var searchText: String = ""
@Binding var showRuns: Bool
@State var tap = false
@State var showActionSheet = false
//States for weeks
@State var hideSunday = false
@State var hideFavorites = false
//View
@State var clubInfo = false
@State private var urlString = ""
@State private var showSafari = false
var body: some View {
ZStack {
VStack {
List {
//TODO: Add section filtering.
HStack {
Text("Run Clubs")
.font(.title).bold()
Spacer()
}
Section(header:
HStack {
Text("Sunday")
.font(.subheadline)
.padding(.vertical, 5)
Image(systemName: hideSunday ? "chevron.up": "chevron.down")
.foregroundColor(Color("carolinablue"))
.rotation3DEffect(Angle(degrees: hideSunday ? 180 : 0), axis: (x: 0, y: 90, z: 0))
}
.animation(.easeInOut(duration: 0.2))
.onTapGesture {
self.hideSunday.toggle()
})
{
if hideSunday == false {
//display data
ForEach(runclubs.filter({
searchText.isEmpty ? true : $0.name.lowercased().contains(searchText.lowercased())
})) { item in
if item.category == "Sunday" {
ZStack {
HStack {
//MARK: Background color
Color(clubInfo ? "carolinablue" : "card3")
.frame(width: 30, height: 575)
.cornerRadius(3)
.frame(width: 6, height: 75, alignment: .leading)
.background(Color( colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.08))
.cornerRadius(3)
.padding()
.frame(width: 3, height: 55)
.background(Color.black.opacity(0.1))
.cornerRadius(12)
.scaleEffect(clubInfo ? 0.8 : 1)
.animation(.interpolatingSpring(mass: 1.0,stiffness: 100, damping: 6.0))
//MARK: Runclub top section
VStack(alignment: .leading, spacing: 8.0) {
HStack {
ZStack(alignment: .leading) {
Text(item.name)
.font(.headline)
.animation(.easeOut(duration: 0.4))
.rotation3DEffect(Angle(degrees: clubInfo ? 90 : 0), axis: (x: 90, y: 0, z: 0))
Text(item.location)
.font(.headline)
.rotation3DEffect(Angle(degrees: clubInfo ? 0 : 90), axis: (x: 90, y: 0, z: 0))
.animation(.easeOut(duration: 0.4))
}
Spacer()
Image(systemName: clubInfo ? "chevron.up": "chevron.down")
.font(.system(size: 20, weight: .medium))
.foregroundColor(Color("carolinablue"))
.rotation3DEffect(Angle(degrees: clubInfo ? 180 : 0), axis: (x: 0, y: 90, z: 0))
.shadow(color: Color("carolinablue"), radius: 12, x: 0, y: 0)
.onTapGesture{
self.clubInfo.toggle()
}
}
//MARK: Runclub bottom section
HStack {
ZStack(alignment: .leading) {
HStack {
Image(systemName: "safari")
Text("Link for more Info")
.font(.subheadline)
.onTapGesture {
self.showSafari = true
self.urlString = item.link
print("urlString \(self.urlString)")
}
Spacer()
}
.animation(.easeOut(duration: 0.4))
.rotation3DEffect(Angle(degrees: clubInfo ? 0 : 90), axis: (x: 90, y: 0, z: 0))
// .allowsHitTesting(clubInfo ? true : false)
HStack {
Text(item.location)
.font(.subheadline)
.rotation3DEffect(Angle(degrees: clubInfo ? 90 : 0), axis: (x: 90, y: 0, z: 0))
Spacer()
//
}
}
.animation(.easeOut(duration: 0.4))
}
}
//testing long press here to prevent scrolling issues.
.onLongPressGesture {
self.showSafari = true
self.clubInfo = false
self.urlString = item.link
}
}
}
.sheet(isPresented: $showSafari) {
SafariView(urlString: self.$urlString)
}
.padding(.horizontal, 15)
.frame(height: 90)
.background(Color(clubInfo ? "background3" : "background2"))
.animation(.easeInOut(duration: 0.3))
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
.shadow(color: Color("background2").opacity(0.8), radius: 10, x: 0, y: 10)
.padding(.vertical, 13)
}
}
}
}
}
}
.padding(.top, 15)
.onTapGesture {
self.hideKeyboard()
}
.navigationBarItems(trailing: EditButton())
}
//MARK: Call for run club data
.onAppear{
print("onappear making API call for data")
Api().getRunClub(url: "https://api.npoint.io/a5a1f2a53b3856ceed34") { (runclubs) in
self.runclubs = runclubs
print("We got the run run clubs")
}
}
.padding(.top, 65)
}
}