Полиморфизм и SwiftUI - PullRequest
       21

Полиморфизм и SwiftUI

2 голосов
/ 06 января 2020

Учитывая следующий пример:

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
                }
            }
        }
    }
}

Есть ли лучший / рекомендуемый способ доступа к свойствам различных классов в моем массиве ProfileTab?

Я знаю, что это приведет к :

Закрытие, содержащее оператор потока управления, нельзя использовать с компоновщиком функций 'ViewBuilder'

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

Есть ли более чистый способ, чем выполнение следующих действий?

(tab as! ProfileImageTab).image

1 Ответ

2 голосов
/ 06 января 2020

В описанном случае использования полиморфизм будет выглядеть следующим образом (или в некоторых вариациях):

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()
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...