Post

Replies

Boosts

Views

Activity

Reply to Moving a MapMarker on a SwiftUI/MapKit Map View
Ignoring the parameter and bypassing it was one of my failed attempts at getting it to work. Ignoring vs not ignoring the parameter seemed to do nothing, though ignoring it is irrational. The version committed to my git repository is as follows (where I chose not to ignore the parameter in the closure): @available(iOS 14.0, *) struct MapView: View { 		@Binding var train: Train 		@Binding var region: MKCoordinateRegion 		 		var body: some View { 				Map(coordinateRegion: $region, interactionModes: .zoom, annotationItems: [train], annotationContent: { (train) in 						return MapMarker.init(coordinate: CLLocationCoordinate2D(latitude: CLLocationDegrees(train.position!.latitude), longitude: CLLocationDegrees(train.position!.longitude))) 				}) 				.edgesIgnoringSafeArea(.bottom) 				.navigationBarTitle("Train #\(train.runNumber)") 		} } @available(iOS 14.0, *) struct MapView_Previews: PreviewProvider { 		@State static var train = sampleTrain1 		@State static var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: sampleTrain1.position!.latitude, longitude: sampleTrain1.position!.longitude), latitudinalMeters: 1000, longitudinalMeters: 1000) 		 		static var previews: some View { 				NavigationView { 						MapView(train: $train, region: $region) 				} 		} }
Jun ’20
Reply to The compiler is unable to type-check this expression in reasonable time in Xcode 12 with SwiftUI
The way that I've gotten around this is by commenting out sections of the view or, in your case, the toolbar. I would build the project a few times so that every section is built at least once. After commenting and correcting any errors that was with the first section that was built, uncomment one of the commented sections and comment the uncommented section and build. Once you've done this for each section, you should be able to uncomment everything and it should succeed in building. This is only a workaround, however. See my example view below: First Build: struct Example: View { 		var body: some View { 				List { 						Section { 							 EmptyView() 						} 						//Section { 							// EmptyView() 						//} 						//Section { 							// EmptyView() 						//} 						//Section { 							// EmptyView() 						//} 		} } Second Build: struct Example: View { 		var body: some View { 				List { 						//Section { 					 //		EmptyView() 					 // } 						Section { 							 EmptyView() 						} 						//Section { 							// EmptyView() 						//} 						//Section { 							// EmptyView() 						//} 		} } And so on until you've built all of your sections. After this you should be able to uncomment everything and it should be able to build everything.
Jul ’20
Reply to is it possible to have SwiftUI single code base for iOS14 and 13?
When you create a new iOS App in Xcode, it should have an option for "UIKit AppDelegate" or something like that. That will create a new project with an AppDelegate and a SceneDelegate. You should then be able to set the minimum deployment target to iOS 13. (Note: Only do this for new projects. For older projects, you can make a new project and copy the AppDelegate.swift and SceneDelegate.swift file from the newer project to the older project and delete the file containing the struct conforming to the App protocol. You can also manually make an AppDelegate.swift and SceneDelegate.swift file, though I am unsure on how one would do that exactly.)
Aug ’20
Reply to How can I make request to an API and then create a view in SwiftUI?
I would recommend using a Combine publisher and then make a class that interfaces with the publisher. You can get a combine publisher from URLSession and then use the built in operators or make some of your own in order to transform the data that you receive to make it easier for SwiftUI to read it. The class that interfaces with the publisher can receive all of its messages and be connected to any SwiftUI view using the @StateObject, @ObservedObject or @EnvironmentObject property wrappers. Make sure that the class interfacing between your publisher and SwiftUI conforms to the ObservableObject protocol (or else it won't work with the aforementioned property wrappers.) I find that the built in operators in Combine work well enough so that creating an operator is usually not required.
Aug ’20
Reply to SwiftUi basic questions
As for your questions: SwiftUI is a UI framework that uses a declarative syntax where you basically tell the framework what you want and the framework figures out how to do it. (AppKit/UIKit/WatchKit use an imperative syntax where you tell the framework what to do) SwiftUI user interfaces can be made using code or using Xcode Previews (you can switch as frequently as you like during the development process, whereas with AppKit/UIKit/WatchKit you have to use Interface Builder (.storyboard files) or code for the entirety of the development process.) SwiftUI does not use storyboards, and I believe it does support Drag and Drop interfaces, but I am not sure about this one. SwiftUI can be integrated with AppKit/UIKit/WatchKit: In order to integrate SwiftUI into one of the other three frameworks, you use a hosting controller and can put a SwiftUI view in it. It seems to be a storyboard reference but for SwiftUI views. For integrating AppKit/UIKit/WatchKit into SwiftUI there are representable protocols (Example: UIViewRepresentable, UIViewControllerRepresentable) where you can make and update your AppKit/UIKit/WatchKit views for SwiftUI. Go through the Tutorials and you will get all the answer you need. I found the tutorials very helpful when learning SwiftUI. There is a section where you integrate with UIKit in order to put a map into the example app.
Aug ’20
Reply to How to filter data from an api, and how to use userdefaults to load and save data?
I would recommend using Core Data instead of UserDefaults, since UserDefaults is designed for smaller scale things like device settings for an app for example. Core Data can easily handle the movie metadata. As for the thumbnail, you can store that too but its a little more complicated. I'm not entirely sure how to do it off the top of my head, but there should be a way to store it. In terms of integrating Core Data with your user interface, you can use the NSFetchedResultsController to connect your UI where you would use the values from the fetched results controller to return as part of the UIKit implementation. I would also recommend that you use Swift's new concurrency support if you're project has an iOS/iPadOS development target of iOS/iPadOS 15.0 or later. It'll make it more difficult to make mistakes such as leaving the caller of your methods hanging by not calling the completion handler by accident.
Dec ’21
Reply to "Sorry, you can’t enroll at this time." when enrolling.
You have to be at least 18 years old to enrol in the Apple Developer Program yourself. There however, I believe, exists a way for you to enrol otherwise. If I am not mistaken, you can enrol using an Apple ID of someone who is over the age of 18 (parent/guardian, for example) and use their account to access the services that the Apple Developer Program provides. I would recommend double checking with Apple Developer Support before continuing.
Jan ’22
Reply to Using an @EnvironmentObject Breaks Xcode Previews
I would recommend trying to put the .environmentObject modifier on the view that you're previewing or the top level group if there are two or more of them. In the modifier you'll have to specify an instance of your environment object. Based on your code sample, you could probably just put SettingsData() in the argument for the modifier to satisfy it. Here's an example of the preview code that might fit your needs (one view) static var previews: some View { SomeView() .environmentObject(SettingsData()) } or more than one view static var previews: some View { Group { SomeView() AnotherView() // Any other views that would be placed here } .environmentObject(SettingsData()) }
Jan ’22
Reply to SwiftUI modifying state warning - pointing to @main
Here's my custom StoredRoutes type: import Foundation final class StoredRoutes: NSObject, NSSecureCoding {     static var supportsSecureCoding: Bool = true     func encode(with coder: NSCoder) {         var routeids: [NSString] = []         for route in routes {             routeids.append(NSString(string: route.rawValue))         }         coder.encode(NSArray(array: routeids), forKey: "routes")     }     init?(coder: NSCoder) {         if let nsArray = coder.decodeObject(of: NSArray.self, forKey: "routes") {             self.routes = []             for id in nsArray {                 self.routes.append(Route(rawValue: id as! String)!)             }         } else {             return nil         }     }     var routes: [Route]     required init(routes: [Route]) {         self.routes = routes     } } and my value transformer: import Foundation final class StoredRoutesValueTransformer: NSSecureUnarchiveFromDataTransformer {          static var name = NSValueTransformerName(rawValue: "StoredRoutesValueTransformer")          override class func allowsReverseTransformation() -> Bool {         return true     }          override class func transformedValueClass() -> AnyClass {         return StoredRoutes.self     }          override class var allowedTopLevelClasses: [AnyClass] {         return [StoredRoutes.self, NSArray.self, NSString.self]     }          override func transformedValue(_ value: Any?) -> Any? {         guard let data = value as? Data else {             fatalError("Wrong data type: value must be of type Data. The type the value recieved was \(type(of: value)).")         }         return super.transformedValue(data)     }          override func reverseTransformedValue(_ value: Any?) -> Any? {         guard let storedRoutes = value as? StoredRoutes else {             fatalError("Wrong data type: value must be of type StoredRoutes. The type of the value recieved was \(type(of: value))")         }         return super.reverseTransformedValue(storedRoutes)     }     public static func register() {         let transformer = StoredRoutesValueTransformer()         ValueTransformer.setValueTransformer(transformer, forName: name)     } }
Jan ’22