Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphism and SwiftUI

Given the following example:

class ProfileTab: Identifiable {
    let id = UUID()
    let name: String

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

class ProfileQuoteTab: ProfileTab {
    let answer: String
    let prompt: String

    init(name: String, answer: String, prompt: String) {
        self.answer = answer
        self.prompt = prompt
        super.init(name: name)
    }
}

class ProfileImageTab: ProfileTab {
    let image: Image

    init(name: String, image: Image) {
        self.image = image
        super.init(name: name)
    }
}

struct ContentView: View {
    let tabs: [ProfileTab] = [
        ProfileQuoteTab(name: "This is a quote tab", answer: "This is an answer", prompt: "This is a prompt"),
        ProfileImageTab(name: "This is an image tab", image: Image(systemName: "faceid"))
    ]

    var body: some View {
        List(self.tabs) { tab in
            VStack {
                if tab is ProfileQuoteTab {
                    Text((tab as! ProfileQuoteTab).answer)
                }

                if tab is ProfileImageTab {
                    (tab as! ProfileImageTab).image
                }
            }
        }
    }
}

Is there a better/recommended way of accessing properties on different classes within my ProfileTab array?

I know doing this will result in:

Closure containing control flow statement cannot be used with function builder 'ViewBuilder'

if let profileImage = tab as? ProfileImage {
    ...
}

Is there a cleaner way rather than doing the following?

(tab as! ProfileImageTab).image

like image 255
fulvio Avatar asked Jan 06 '20 05:01

fulvio


People also ask

What is polymorphism in Swift?

polymorphism is about provisioning a single interface to entities of different types. Although it is usually underestimated, it is one of the most powerful concepts in software engineering that lets you define different behaviors for different objects while you are still using a shared interface among them.

Can a Swiftui view be a class?

The short answer: no.

What is polymorphism in Swift?

Polymorphism (in Swift) In the context of Object Oriented Programming, this means the provision of a single interface to entities of different types. The interface provided by the objects is the same, but what’s going on under the hood might vary depending on, perhaps, the message sent, or the type passed to a particular function for example.

What is polymorphism in C++?

Polymorphism is the method in an object-oriented programming language that performs different things as per the object’s class, which calls it. With Polymorphism, a message is sent to multiple class objects, and every object responds appropriately according to the properties of the class.

What is the difference between polymorphism and inheritance?

Polymorphism is a mechanism to dynamically decide what form of a function should be invoked. Polymorphism allows the expression of common behavior between types of objects which have similar traits. Inheritance can be thought of as one of the mechanisms we can use to achieve polymorphism in our code via the use...

What are the different types of polymorphism in Oops?

In Object-Oriented Programming (OOPS) language, there are two types of polymorphism as below: 1. Compile Time or Static Polymorphism With Method Overloading, static polymorphism is achieved in Object-Oriented Programming languages that allow the programmer to implement various methods.


Video Answer


1 Answers

In the described use-case the polymorphism would look like the following (or in some variations):

class ProfileTab: Identifiable {
    let id = UUID()
    let name: String

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

    func view() -> AnyView {
        AnyView(EmptyView())
    }
}

class ProfileQuoteTab: ProfileTab {
    let answer: String
    let prompt: String

    init(name: String, answer: String, prompt: String) {
        self.answer = answer
        self.prompt = prompt
        super.init(name: name)
    }

    override func view() -> AnyView {
        AnyView(Text(self.answer))
    }
}

class ProfileImageTab: ProfileTab {
    let image: Image

    init(name: String, image: Image) {
        self.image = image
        super.init(name: name)
    }

    override func view() -> AnyView {
        AnyView(self.image)
    }
}

struct ContentView: View {
    let tabs: [ProfileTab] = [
        ProfileQuoteTab(name: "This is a quote tab", answer: "This is an answer", prompt: "This is a prompt"),
        ProfileImageTab(name: "This is an image tab", image: Image(systemName: "faceid"))
    ]

    var body: some View {
        List(self.tabs) { tab in
            VStack {
                tab.view()
            }
        }
    }
}
like image 127
Asperi Avatar answered Oct 19 '22 23:10

Asperi