Post

Replies

Boosts

Views

Activity

Reply to TextField .alignmentGuide in Form leading point varies?
Originally I just passed a label to the actual TextField but could not get the desired effect. This is the solution I'm using but I find it unsatisfactory. I wrap each form item in LabeledContent. It does not look as tidy as the Form label formatting but without it when I use .alignmentGuide it operates from a unique origin which depends on the label but simply adjusting for the label length does not give consistent results. Form { LabeledContent { CustomField( thing: $activeThing, setValue: { thingtype, newValue in thingtype.thing = newValue } ) } label: { Text(shortLabel) .frame(width: longLabelWidth, alignment: .trailing) } CustomField( thing: $activeThing, setValue: { thingtype, newValue in thingtype.thing = newValue } ) } label: { Text(longLabel) .frame(width: longLabelWidth, alignment: .trailing) } } struct CustomField: View { ... var body: some View { TextField("", text: $displayText) .inlineCompletion( text: displayText, completion: completion, ) .onAppear {displayText = getValue(transaction)} struct InlineCompletion: ViewModifier { let text: String let completion: String func body(content: Content) -> some View { ZStack(alignment: .leading) { content if !completion.isEmpty { Text(completion) .foregroundColor(.secondary) .opacity(text.isEmpty ? 0 : 0.7) .alignmentGuide(.leading) { _ in -textWidth(text) - baseFontSize } } } } } extension View { func inlineCompletion(text: String, completion: String) -> some View { modifier( InlineCompletion( text: text, completion: completion ) ) } }
Topic: UI Frameworks SubTopic: SwiftUI
Feb ’25
Reply to NSExpression error handling
Thanks for making that clear. For the sake of helping anyone else with this issue, my solution is to use a pair of functions which cleans the typed expression as best it can but then calmly handles errors on any remaining malformed input private func handleSubmit() { print("handling submit") if let result = safelyEvaluateExpression() { inputExpression = result isError = false } else { isError = true } } private func safelyEvaluateExpression() -> String? { let preparedExpression = inputExpression .replacingOccurrences(of: "×", with: "*") .replacingOccurrences(of: "÷", with: "/") .trimmingCharacters(in: .whitespacesAndNewlines) guard !preparedExpression.isEmpty else { return nil } let allowedChars = CharacterSet(charactersIn: "0123456789.+-*/() ") guard preparedExpression.unicodeScalars.allSatisfy({ allowedChars.contains($0) }) else { return nil } if let result = NSExpressionWrapper.evaluateExpression(preparedExpression) { return String(format: "%.2f", result.doubleValue) } return nil } with: // NSExpressionWrapper.h #import <Foundation/Foundation.h> @interface NSExpressionWrapper : NSObject + (NSNumber *)evaluateExpression:(NSString *)string; @end and // NSExpressionWrapper.m #import "NSExpressionWrapper.h" @implementation NSExpressionWrapper + (NSNumber *)evaluateExpression:(NSString *)string { @try { NSExpression *expression = [NSExpression expressionWithFormat:string]; return [expression expressionValueWithObject:nil context:nil]; } @catch (NSException *exception) { // Log if needed NSLog(@"Caught exception: %@", exception.reason); return nil; // Return nil on error } } @end In the SwiftUI code I use isError to overlay the TextField to let the user know they have work to do. Claude helped me with this code. I am not a programmer. I'm disappointed that I need to use Obj-C code and not stick to Swift in order to allow simple inline math but perhaps with the advent of math in apps like Notes there will be a Swift solution in the future.
Topic: Programming Languages SubTopic: Swift Tags:
Jan ’25
Reply to Recursion in a SwiftUI Table
I've not gotten anywhere with this. The issue is how does one abstract code from within a DisclosureTableRow and return either another DisclosureTableRow or a TableRow. Why not organize the accounts hierarchically and feed that to Table? Because then childless parents have disclosure triangles and there are issues with expansion.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’24
Reply to .dropDestination on TableRow updated recently?
My solution, which I learned from elsewhere on this forum, is just to drag the unique name property of my object as a String and then in the action closure use the name to find the dropped object. Interestingly, when I try to abstract this modifier the compiler expects the elements that prevent compilation; perhaps this would work with something more specific than some View. struct DropableTableRowModifier: ViewModifier { let object: Object: func body(content: Content) -> some View { content .dropDestination(for: String.self) { objectNames in // do things with object and objectNames return }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’24