9

I am trying to replicate the way we can create a function with a default optional parameter in swiftui.

func greet(_ person: String, nicely: Bool = true) {
    if nicely == true {
        print("Hello, \(person)!")
    } else {
        print("Oh no, it's \(person) again...")
    }
}

Which could be called in two different ways

greet("Taylor")
greet("Taylor", nicely: false)

Is it possible to create a SwiftUI view with this same logic? I would like to create a component that has a 'default optional' parameter so I could call it as:

DividerItem(...)
DividerItem(..., isBold: true)

Many thanks!

3 Answers 3

10

Here you go... just define the variables of your View, give them default and you can call them with two different intializations

struct ContentView: View {
    
    var body : some View {
        DividerItem(text: "Hello World", isBold: true)
        DividerItem(text: "Hello Second World")
    }
}


struct DividerItem : View {
    
    var text : String
    var isBold = false
    
    var body : some View {
        Text(text)
            .fontWeight(self.isBold ? .bold : .medium)
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer! I was slightly confused, trying var isBold?: Bool = true
Thats two different things. You might declare your isBold as optional. Then it can be nil. Hence, you won't need to declare a default value aswell, as the default value is nil. If you want to make sure isBold has always a valid value, you provide a default parameter without declaring it was optional.
4

You can create a custom initialiser for your view

struct DividerItem : View {
    var isBold: Bool
    // other properties

    init(/* other params */ isBold: Bool = false) {
        self.isBold = isBold
    }

    var body: some View {
        //....
    }
}

and then call it with or without the boolean parameter

DividerItem(/* other params */)
DividerItem(/* other params */ isBold: true)

2 Comments

What are the differences between both solutions? I personally prefer the first one as it seems less coding. Thank you.
@jmrueda Mostly a matter of taste and I primarily posted this to show there is another option. And sometimes you might need to have an init anyway for other reasons so then this is usable
0
struct MetricCardView: View {
    var title: String
    var value: String
    var color: Color
    var width: CGFloat
    var iconName: String?
    var iconDecription: String?


    var body: some View {
        VStack {

    if let iconName = iconName, let iconDecription = iconDecription {
                Label(iconName, systemImage: iconDecription)
            }
           
            Text(title)
                .font(.headline)
            Text(value)
                .font(.largeTitle)
                .fontWeight(.bold)
        }
        .frame(width: width, height: 100)
        .background(color.opacity(0.2))
        .cornerRadius(10)
    }
}

now you can call the MetricCardView() and for any of the two var marks as question mark

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.