NEW: Learn to build amazing SwiftUI apps for macOS with my new book! >>

SOLVED: Question: why this View struct doesn't have initializer ?

Forums > 100 Days of SwiftUI

So, I am watching/reading Paul's view composition session

https://www.hackingwithswift.com/books/ios-swiftui/view-composition

He wrote this to demonstrate how to make small chunks of views and place them in they body view .

struct CapsuleText: View {
    var text: String

    var body: some View {
        Text(text)
            .font(.largeTitle)
            .padding()
            .foregroundColor(.white)
            .background(.blue)
            .clipShape(Capsule())
    }
}

struct ContentView: View {
    var body: some View {
        VStack(spacing: 10) {
            CapsuleText(text: "First")
            CapsuleText(text: "Second")
        }
    }
}

And, same thing happened in the session right after the previous one https://www.hackingwithswift.com/books/ios-swiftui/custom-modifiers

Custom modifiers, they are also structs , but they are just directly placed in the body view without initializer.

This is what Paul wrote:


struct Title: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.largeTitle)
            .foregroundColor(.white)
            .padding()
            .background(.blue)
            .clipShape(RoundedRectangle(cornerRadius: 10))
    }
}

struct ContentView: View {
    var body: some View {
     Text("Hello World")
          .modifier(Title())

Again, no initializer.

My question:

struct CapsuleText: View and struct Title: ViewModifier are still struct, shouldn't there be initializer somewhere before it was placed the body view?

1      

All Structs get a free initializer.

See this article for details.

Free Initializers for Structs

2      

Thank you @Obelix, very happy to see you . I was wondering when you will show up !

Yes I know the idea of memberwise initializer, but it seems that everytime in our projects/challenges, Paul is always writing initializers, and it makes me nervous when I don't see one, becuase so many times Xcode warns me "there's no initializer". I am completely lost on when should use memberwise initializer and when to write them ourselves. (Theoritically I know, but when it comes to practice, it is still so confusing)

Initiazlier is becoming my biggest nightmare. It is haunting me everywhere.

1      

Classes need you to write an initializer. You must tell classes, "When you create yourself, here are your initial values. But you must use this initializer to set everything up." (Unless you initialize all your vars with default values.)

With Structs, you can just say "Create yourself, and here are your starting values." The struct will know how to assign values to its vars and lets without having a specific initializer. Not sure what lessons you are watching at the moment, but @twostraws gradually introduces more complex topics after you've been comfortable with the basics.

So when you watch a video where he's creating an initializer for a Struct, ask yourself "WHY? Why is he creating an initializer??" Most likely you should be learning a new technique. Discover the reason behind the Struct's initializer, and take notes.

In future, when designing your own Structs, you'll have several techniques to consider.

  1. Use the (free) memberwise initializer.
  2. Write a custom initializer.
  3. Write several initializers with customized parameters.

There is no ONE way to do this. You have to consider your struct's requirements, and select the correct technique.

So if you examine the CapsuleText() struct, you'll see it requires just one parameter, a String. Do you need to write an initializer for this? Probably not. Use Technique #1, the free initializer.

But when you get to Views that are customized components, perhaps containing a Slider, or some other control, you'll have to have bindings. These may require you to think about the struct's requirements. And no, the free initializer may not work for those views.

This is when you'll want to refer to your excellent notes!

2      

Classes need you to write an initializer. You must tell classes, "When you create yourself, here are your initial values. But you must use this initializer to set everything up."

You don't have to write an initializer for a class if you supply default values to all its properties.

This is perfectly fine:

class Thing {
    let name: String = ""
    let address: String = ""
}

let t = Thing()

2      

Every struct has a memberwise initializer so if you had this

struct Thing {
    let name: String
    let address: String
}

then the complier does this automatically

struct Thing {
    let name: String
    let address: String

    init(name: String, address: String) {
        self.name = name
        self.address = address
    }
}

However you can customize the init() which is what Paul sometime does. eg

struct Thing {
    let name: String
    let address: String

    init(name: String) {
        self.name = name
        self.address = "Address"
    }
}

Note If you have a customize initializer you will lose the memberwise initializer

However as @roosterboy says classes must have a initial value or a init()

2      

Thank you boys @Obelix, @roosterboy and @NigelGee

@NigelGee , thanks for the example. So, for Structs, we only write our own initilizer when we want to customerize it.

Got it.

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Spend less time managing in-app purchase infrastructure so you can focus on building your app. RevenueCat gives everything you need to easily implement, manage, and analyze in-app purchases and subscriptions without managing servers or writing backend code.

Get Started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.