Post

Replies

Boosts

Views

Activity

Most efficient way to call a function upon variable state change
Hi, I have a button view that is used in many different ways in an app that I'm working on. One of the ways it is used is in an account creation form. Since the button is in a child view, the action: { } button function isn't available in the view where the input field variables are. I could import the class with the function to the button view but I don't want to pass the input field variables into the button view. I tried binding a boolean variable to the button view and checked for it's state change in the parent view using .onChange(), but the use case for that I found was depreciated and I'm unable to revert the state of the variable in the .onChange function. To reiterate, in a main view, I need to call a function in a given class and pass variables to it, upon a button being pressed in a child view. Any help would be greatly appreciated.
2
0
1.2k
Jul ’24
Implementing multiple Model Containers
Hi, When using just one model container, I have the following code: let modelContainer: ModelContainer init() { do { entriesModel = try ModelContainer(for: Model.self) } catch { fatalError("Could not initialize ModelContainer") } } I am attempting to implement two like so: let model1: ModelContainer let model2: ModelContainer init() { do { model1 = try ModelContainer(for: Model1.self) model2 = try ModelContainer(for: Model2.self) } catch { fatalError("Could not initialize ModelContainer") } } var body: some Scene { WindowGroup { ContentView() .modelContainer(model1) .modelContainer(model2) } } However, when in the Views that I'd like to implement I don't know how to declare the models. I tried this: @Environment(\.model1) private var model1 @Query private var data: [Model1] But I get the error: Cannot infer key path type from context; consider explicitly specifying a root type How do I implement multiple model containers in multiple different views?
2
0
1.8k
Oct ’24
Thread Error with @Model Class
I have a @Model class that is comprised of a String and a custom Enum. It was working until I added raw String values for the enum cases, and afterwards this error and code displays when opening a view that uses the class: { @storageRestrictions(accesses: _$backingData, initializes: _type) init(initialValue) { _$backingData.setValue(forKey: \.type, to: initialValue) _type = _SwiftDataNoType() } get { _$observationRegistrar.access(self, keyPath: \.type) return self.getValue(forKey: \.type) } set { _$observationRegistrar.withMutation(of: self, keyPath: \.type) { self.setValue(forKey: \.type, to: newValue) } } } Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1cc165d0c) I removed the String raw values but the error persists. Any guidance would be greatly appreciated. Below is replicated code: @Model class CopingSkillEntry { var stringText: String var case: CaseType init(stringText: String, case: CaseType) { self.stringText = stringText self.case = case } } enum CaseType: Codable, Hashable { case case1 case case1 case case3 }
2
0
507
Oct ’24
Cannot convert value of type '() -> ()' to expected argument type 'String' SwiftUI Button
Hello, I'm trying to build a simple button. For some reason, I'm getting the following errors: Cannot convert value of type '() -> ()' to expected argument type 'String' Incorrect argument label in call (have 'action:_:', expected 'value:selected:') Button(action: login) { ZStack { RoundedRectangle(cornerRadius: 5) .fill(Color.black) .frame(width: UIScreen.main.bounds.width - 50, height: 50) Text("Sign in") .foregroundColor(.white) } } All of my buttons in this particular project suddenly have this error. Any help would be greatly appreciated. Thank you
3
0
1.4k
Dec ’23
Using the SwiftUI Canvas
Hello, I was following a tutorial on how to use the SwiftUI Canvas and I can't seem to get it to work. Below is the code that I have. struct Line { var points: [CGPoint] var color: Color } struct CanvasView: View { @State var lines: [Line] = [] @State var selectedColor: Color = Color.black var body: some View { ScrollView([.horizontal, .vertical]) { Canvas { ctx, size in for line in lines { var path = Path() path.addLines(line.points) ctx.stroke(path, with: .color(line.color), style: StrokeStyle(lineWidth: 5, lineCap: .round, lineJoin: .round)) } }.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local) .onChanged({ value in let position = value.location if value.translation == .zero { lines.append(Line(points: [position], color: selectedColor)) } else { guard let lastIndex = lines.indices.last else { return } lines[lastIndex].points.append(position) } }) ) } } } I'm pretty sure I followed the tutorial exactly so I'm not sure why it isn't drawing. Any help would be greatly appreciated. Thank you.
3
0
2.3k
Feb ’24
Efficiently accounting for different iOS versions
I one project, using .onChange(), I get an error: 'onChange(of:initial:_:)' is only available in iOS 17.0 or newer The solution provided is to wrap the code in if #available(iOS 17.0, *) { }, but I'm only able to wrap the whole view inside of it, like so: if #available(iOS 17.0, *) { VStack () { // view with .onChange } } else { VStack () { // view with older solution } } The view is quite lengthy so it would be very redundant to have the same view twice, (the same view for each component of the if/else statement). Is there a way to implement an if statement so that I would only need the code for the view once (something like the code below)? VStack { } if #available(iOS 17.0, *) { .onChange() { } } else { // older solution } Additionally, in a newer project, I don't have to include the if #available(iOS 17.0, *) { }, so I'm guessing the build is made for a newer iOS. If that's the case, would it not be compatible with older iOS versions? Any help would be greatly appreciated.
Topic: Design SubTopic: General Tags:
3
0
1.1k
Jul ’24
Issues with UserDefault boolean
Hi, I have a view that should do the following: Set up and confirm a passcode upon account creation. Verify passcode if signing in. Reset passcode if prompted. With the code below, functions 1 and 2 are working. However, I'm having an issue with function 3. I am able to declare the reset UserDefault on a previous view so that the proper logic occurs, which is to read in the input, and then confirm it. However, it is not working as intended. In this code here: else if reset { UserDefaults.standard.set(passcode, forKey: "new-passcode") UserDefaults.standard.set(false, forKey: "reset-passcode") passcode = "" } I store the new passcode, set reset to false, and clear the passcode so it can be entered again to confirm. The code does not run as intended however. The title does not change and I'm unsure if it is actually storing the passcode. And, when re-entering, it does not change the view as it should by setting view = .someView. I'm assuming there is just flaw in my logic but I'm not sure how to resolve this. Below is the full code. Please let me know if any further clarification is needed. struct EnterPasscode: View { @State var title = "" @State var passcode = "" @State var message = "" @State var buttonState = false @Binding var view: Views var body: some View { Group { Spacer() .frame(height: 50) Text(title) .font(.system(size: 36)) .multilineTextAlignment(.center) .frame(height: 50) Spacer() if passcode != "" { Text("\(passcode)") .font(.system(size: 24)) .frame(height: 25) } else { Spacer() .frame(height: 25) } Spacer() .frame(height: 50) PasscodeKeypad(passcode: $passcode) Spacer() if message != "" { Text(message) .frame(height: 25) .foregroundStyle(Color.red) } else { Spacer() .frame(height: 25) } Spacer() WideButton(text: "Continue", buttonFunction: .functional, openView: .enterPasscode, view: .constant(.enterPasscode), buttonState: $buttonState) .onChange(of: buttonState) { oldState, newState in if buttonState { let passcodeSet = UserDefaults.standard.bool(forKey: "passcode-set") let storedPasscode = UserDefaults.standard.string(forKey: "passcode") let reset = UserDefaults.standard.bool(forKey: "passcode-reset") let newPasscode = UserDefaults.standard.string(forKey: "new-passcode") print(reset) if passcode.count == 4 { if storedPasscode == nil { if newPasscode == nil { UserDefaults.standard.set(passcode, forKey: "new-passcode") passcode = "" } else if passcode == newPasscode { UserDefaults.standard.set(passcode, forKey: "passcode") UserDefaults.standard.set(true, forKey: "passcode-set") view = .someView } } else if reset { UserDefaults.standard.set(passcode, forKey: "new-passcode") UserDefaults.standard.set(false, forKey: "reset-passcode") passcode = "" } else if newPasscode != nil { if passcode == newPasscode { UserDefaults.standard.set(passcode, forKey: "passcode") view = .someView } } } checkPasscodeStatus() buttonState = false } } Spacer() if !UserDefaults.standard.bool(forKey: "passcode-reset") && UserDefaults.standard.bool(forKey: "passcode-set") { Button(action: { view = .verifyPhone }) { Text("Forgot passcode?") .foregroundStyle(.black) } } Spacer() .frame(height: 25) } .onAppear() { checkPasscodeStatus() } .frame(width: UIScreen.main.bounds.width - 50) } func checkPasscodeStatus() { let passcodeSet = UserDefaults.standard.bool(forKey: "passcode-set") let storedPasscode = UserDefaults.standard.string(forKey: "passcode") let reset = UserDefaults.standard.bool(forKey: "passcode-reset") if reset { title = "Enter new passcode" } else if passcodeSet { title = "Enter Passcode" } else if storedPasscode != nil && storedPasscode != "" { title = "Confirm Passcode" } else { title = "Select a 4 Digit Passcode" } } } struct WideButton: View { @State var text: String @State var buttonFunction: ButtonType @State var openView: Views? @Binding var view: Views @Binding var buttonState: Bool var body: some View { Button(action: { buttonPressed() }, label: { ZStack { RoundedRectangle(cornerRadius: 5) .fill(Color.black) .frame(width: UIScreen.main.bounds.width - 50, height: 50) Text(text) .foregroundColor(.white) } }) } func buttonPressed() { switch buttonFunction { case .openView: view = openView! case .functional: buttonState = true } } } enum ButtonType { case openView case functional }
Topic: Design SubTopic: General Tags:
3
0
789
Nov ’24
Rendering Multi-Page PDF
I have the following code for generating a one page PDF: @MainActor func render() -> URL { let renderer = ImageRenderer(content: pdfView)) let url = URL.documentsDirectory.appending(path: "output.pdf") renderer.render { size, context in var document = CGRect(x: 0, y: 0, width: 2550, height: 3300) guard let pdf = CGContext(url as CFURL, mediaBox: &document, nil) else { return } pdf.beginPDFPage(nil) context(pdf) pdf.endPDFPage() pdf.closePDF() } return url } I'm trying to write code to create a multi-page PDF if there is multiple ImageRenderers. I tried something shown below but I'm not sure how to properly implement. @MainActor func render() -> URL { let renderer = ImageRenderer(content: pdfView) let url = URL.documentsDirectory.appending(path: "output.pdf") for image in renderer { image.render { size, context in var page = generatePage(image: image) } } return url } func generatePage(image: ImageRenderer<<#Content: View#>>) -> CGContext { var view = CGRect(x: 0, y: 0, width: 2550, height: 3300) guard let pdf = CGContext(url as CFURL, mediaBox: &view, nil) else { return } pdf.beginPDFPage(nil) context(pdf) pdf.endPDFPage() pdf.closePDF() return pdf } Any guidance would be greatly appreciated. Thank you.
3
0
385
Feb ’25
Using Swift UI Canvas
Hello, I am trying to use the SwiftUI canvas and I'm having a couple of issues. One is that I'd like to be able to fit a canvas view in a ScrollView, but when the canvas is inside a ScrolLView, nothing draws. Additionally, I'm trying to draw lines on the canvas on Appear, but I can't seem to get that to work either. Below is a simplified version of the code I have: struct Line: Codable, Hashable { var points: [CGPoint] var colorName: String? var rgb: [Double]? private enum CodingKeys: String, CodingKey { case points case colorName case rgb } } extension CGPoint: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(x) hasher.combine(y) } } struct CanvasExample: View { @State var lines: [Line] = [] @State var selectedColor: Color = Color.black var body: some View { Canvas { ctx, size in for line in lines { var path = Path() path.addLines(line.points) ctx.stroke(path, with: .color(line.color), style: StrokeStyle(lineWidth: 5, lineCap: .round, lineJoin: .round)) } }.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local) .onChanged({ value in let position = value.location if value.translation == .zero { lines.append(Line(points: [position], color: selectedColor)) } else { guard let lastIndex = lines.indices.last else { return } lines[lastIndex].points.append(position) } }) ) .onAppear { lines.append(Line(points: [position], color: .black)) } } } Any help would be greatly appreciated. Thank you.
4
0
1.4k
Jan ’24
Download Rendered PDF
I need to render a PDF and then make it downloadable to the mobile device. I can generate the PDF but I'm unsure how to configure the download aspect. I have the following code: let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 612, height: 792)) let pdf = renderer.pdfData { (context) in context.beginPage() let text = "Test" as NSString text.draw(in: CGRect(x: 0, y: 0, width: 100, height: 25))
4
0
795
Jan ’25
Subscriptions Not Displaying
I have a subscription group with two individual subscriptions configured but when trying to load the SubscriptionStoreView I get the error: "Subscription Unavailable: The subscription is unavailable in the current storefront." When I try to load the ProductView, it appears to be stuck in a loading screen. I am running the app on a device that is signed into a sandbox account. Any guidance would be greatly appreciated. Thank you.
Topic: Design SubTopic: General Tags:
5
0
907
Feb ’25