Post

Replies

Boosts

Views

Activity

Reply to What exactly does the fixedSize() modifier do?
I added a debug print statement to your code as follows: Canvas { gc, size in gc.translateBy(x: 20.0, y: 20.0) gc.stroke( Path(roundedRect: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 200.0), cornerSize: CGSize(width: 2.0, height: 2.0)), with: .color(.black), lineWidth: 20.0 ) print("Width: \(size.width) Height: \(size.height)") } ...and changed ContentView to this: VStack { RRectPlay() RRectPlay() .fixedSize() } …and got the following output in the console: Width: 361.0 Height: 709.0 Width: 10.0 Height: 10.0 So I think it's obvious what's happening here: SwiftUI thinks that the "ideal size" of your custom view is 10x10, which is so small that basically everything gets clipped out. Some ways that you could solve this problem: Specify minimum, maximum, and ideal dimensions of your custom view using frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:) to modify your Canvas object. Draw your Path using arguments calculated relative to size instead of using arbitrary values. This would allow the user of your view to specify their own frame size and have your drawing scale automatically. If you need a rounded rectangle, consider using SwiftUI's RoundedRectangle which handles all of these concerns for you.
Dec ’22
Reply to Loading Custom SF Symbols remotely
First of all, I don't think that AsyncImage can display SVG images at all. For example, try: AsyncImage(url: URL(string: "https://svgshare.com/i/ouu.svg")) { phase in if let image = phase.image { image } else if phase.error != nil { Text("Error.") } else { ProgressView() } } This code displays "Error." with every SVG that I've tried, both from svgshare.com and other websites. The easy solution is to use on-demand resources. This would, however, require that every symbol that your app could potentially use be included with the app store submission, which may not be what you are looking for. A more difficult solution would be to host custom bundles remotely, then, as needed, download those, and use something like Image("customSymbol", bundle: downloadedBundle). Bundle objects can be initialized with a URL, but I don't know if this means that the URL can be on the internet. All the documentation says is, "This must be a full URL for a directory; if it contains any symbolic links, they must be resolvable." It is not clear if the directory can be on a web server. I have no experience with custom bundles, so unfortunately I cannot assist further. If you find a solution, I would love to learn about it. Documentation Links: On-Demand Resources Image.init(_:bundle:) Bundle Bundle Programming Guide
Dec ’22
Reply to Is there a cleaner way of making an enum with associated value conform to rawRepresentable?
Here's another one I came up with, using struct instead of enum: public struct IconColor: RawRepresentable {     public enum StandardColors: String {         case regular = "icon_regular"         case error = "icon_error"         case warning = "icon_warning"         case success = "icon_success"     }     public var rawValue: String     public init(rawValue: String) {         self.rawValue = rawValue     }     public init(_ standardValue: StandardColors) {         self.rawValue = standardValue.rawValue     }     public init(_ customValue: String) {         self.rawValue = customValue     } } // ... let successColor = IconColor(.success) let customColor = IconColor("icon_custom") var rawCustomColor = IconColor(rawValue: "icon_rawcustom")
Sep ’22
Reply to Is there a cleaner way of making an enum with associated value conform to rawRepresentable?
It's not exactly what you were looking for, but maybe you can make this work? public enum IconColor {     public enum Standard: String {         case regular = "icon_regular"         case error = "icon_error"         case warning = "icon_warning"         case success = "icon_success"     }     case standard(Standard)     case custom(String)     public var rawValue: String {         switch self {         case .standard(let standardCase):             return standardCase.rawValue         case .custom(let value):             return value         }     } } Then it could be used like this: let x = IconColor.Standard.success let y = IconColor.custom("icon_deviceonfire") print(x.rawValue)    // Prints "icon_success" print(y.rawValue)    // Prints "icon_deviceonfire"
Sep ’22
Reply to Fill an array with String variable
Polyphonic's answer is correct: Images3 needs to be initialized in init(). Swift will never allow you to set a struct member's value to another struct member's value in the struct declaration itself. This is best illustrated by example: struct ThisNeverWorks {     var a = 1     var b = a    // Error. Cannot do this. } struct DoThisInstead {     var a = 1     var b: Int     init() {         b = a     } } The exception is if right-hand value is a static member: struct ThisWorks {     static let a = 1     var b = a    // This is fine because a is static. } Another consideration, however: will the values of Empty_image, Abductor_machine_image, etc. ever change? If not, then consider making them static let constants (or perhaps even an enumeration). Otherwise, this could happen: struct MyWorkout {     var Empty_image = ""     var Abductor_machine_image = "Abductor machine"     let Images3: [String]     init() {         Images3 = [Empty_image, Abductor_machine_image]     } } // ... var x = MyWorkout() x.Empty_image = "Something"    // No longer empty. I would love to help you learn if you're willing to share in more detail what you're trying to do.
Sep ’22
Reply to Interpolating corner radius with matched geometry effect
Yes, there is: don't use two RoundedRectangles. 🙂 Instead, use one and mutate the values that you want to differ. Here's how I implemented it in your code: struct ContentView: View {     @State var toggled = false     @Namespace var namespace     var body: some View {         VStack(spacing: 16) {             Toggle("Toggle", isOn: $toggled.animation(.linear(duration: 30)))             if toggled {                 Spacer()             }             RoundedRectangle(cornerRadius: toggled ? 24 : 12, style: .continuous)                 .fill(toggled ? .red : .blue)                 .matchedGeometryEffect(id: "box", in: namespace)                 .frame(width: toggled ? 200 : 100, height: toggled ? 100 : 200)             if !toggled {                 Spacer()             }         }         .padding(24)     } } How it works: toggled ? value1 : value2 returns value1 if toggled is true or value2 if toggled is false. This works for anything as long as both values are of the same type. @State tells SwiftUI to update the view any time that toggled changes. So any time you flip the switch, it toggles toggled which forces a recalculation of the view with new values for cornerRadius, .fill, width, and height, and after the recalculation, animates the changes according to your .animation parameters. I think this gives precisely the kind of animation that you were looking for. So any time you want to do something like this, instead of having two views that you switch between, use one view and mutate its values.
Jun ’22