Как обойти приведение общих типов в Swift
У меня есть такой код
import SwiftUI
struct TabItemModifier<TabItem>: ViewModifier where TabItem: View {
var tabItem: () -> TabItem
func body(content: Content) -> some View {
return TabItemView(tabItem: tabItem, content: content)
}
}
struct TabItemView<TabItem, Content> : View where Content: View, TabItem : View {
var tabItem: () -> TabItem
var content: Content
var body: some View {
content
}
}
extension View {
func withTabItem<V>(@ViewBuilder _ label: @escaping () -> V) -> some View where V: View{
ModifiedContent(content: self, modifier: TabItemModifier(tabItem: label))
}
}
Он применяет модификатор withTabItem, который должен возвращать некоторый тип TabItemView, который содержит tabItem и контент в свойствах и отображает только контент.
Затем в другом месте кода я хотел бы передать View в этот TabItemView для доступа к свойству tabItem из него, как показано ниже:
if let tabbed = views.0 as? TabItemView {
tabItems.append(tabbed.tabItem())
}
Но такой кастинг невозможен.
ОБНОВИТЬ
Я изменил это так
var body: some View {
MenuView {
Page1()
Page2()
.menuTabItem(tag: 1) {
TabItemView(systemImage: "person", title: "Tab 2")
}
И новая реализация этого ViewModifier очень проста, вот так
func menuTabItem<T>(tag: Int, @ViewBuilder _ tabItem: @escaping () -> T) -> some View
where T: View {
ModifiedContent(content: AnyView(self),
modifier: Click5MenuItemModifier(
tag: tag,
menuItem: nil,
tabItem: AnyView(tabItem())
)
)
}
struct MenuItemModifier: ViewModifier {
var tag: Int
var menuItem: AnyView?
var tabItem: AnyView?
func body(content: Content) -> some View {
return content
}
}
Но проблема в том, что я могу использовать его только непосредственно внутри MenuView. Использование этого модификатора внутри Page1() приводит к тому, что это представление скрыто под Page1, а затем внутри реализации MenuView я не могу получить доступ к этому модификатору с приведенным выше приведением, также нет ссылки на эту цепочку модификаторов.
1 ответ
TabItemView
- структура имеет два связанных типа. При его использовании необходимо указать конкретный тип. Что-то типа...as? TabItemView<Text, Color>
. Однако указать непрозрачный тип (View
). Итак, мое предложение:
+ Изменить TabItemView
с content
к AnyView
и хранить tabItem
тип должен быть таким же, как tabItems
типа.