Это больше синтаксический вопрос. Я пытаюсь передать представление в инициализатор ViewModifier без использования AnyView.
В настоящее время у меня есть что-то, работающее с использованием AnyView, но я хотел бы использовать общий синтаксис представления, как если бы вы передавали «некоторое представление» представлению, описанному в этом ответе здесь:
Как передать одно представление SwiftUI в качестве переменной в другую структуру представления
Кажется, я не могу заставить его работать с ViewModifier.
Намерение (как показано в образце) состоит в том, чтобы модификатор передал вычисленное значение в innerView. Я также был бы рад использовать @ViewBuilder как-то для указания свойства innerView, поскольку это, вероятно, имело бы тот же эффект.
Вот пример модификатора:
struct SampleModifier: ViewModifier {
let param1: CGFloat
let innerView: (CGFloat, CGFloat) -> AnyView
// Assume these are calculated states
let calculatedParam1: CGFloat = 100
let calculatedParam2: CGFloat = 100
func body(content: Content) -> some View {
ZStack {
HStack {
Spacer()
innerView(self.calculatedParam1, self.calculatedParam2)
.padding(.leading, 10)
.frame(width: param1)
}
content.frame(width: 100, height: 100)
}
}
}
И его использование:
struct SampleView: View {
var body: some View {
Rectangle()
.modifier(SampleModifier(param1: 150, innerView: { param1, param2 in
return AnyView(
Text("Inner View: \(param1) - \(param2)")
)
}))
}
}
Вы можете использовать дженерики, т. е. заставить innerView
возвращать некоторое представление:
struct SampleModifier<V>: ViewModifier where V: View {
let param1: CGFloat
let innerView: (CGFloat, CGFloat) -> V
...
}
Тогда вам больше не нужно AnyView
:
struct SampleView: View {
var body: some View {
Rectangle()
.modifier(SampleModifier(param1: 150, innerView: { param1, param2 in
Text("Inner View: \(param1) - \(param2)")
}))
}
}
Кроме того, вы можете создать расширение View
:
extension View {
func sampleModifier<V>(
param1: CGFloat,
innerView: @escaping (CGFloat, CGFloat) -> V
) -> some View where V: View {
modifier(SampleModifier(param1: param1, innerView: innerView))
}
}
и используйте его так:
struct SampleView: View {
var body: some View {
Rectangle()
.sampleModifier(param1: 150, innerView: { param1, param2 in
Text("Inner View: \(param1) - \(param2)")
})
}
}
@Slappy Я обновил свой ответ расширением View.
Блин, это ИМЕННО то, что я искал. Еще один вопрос: если бы мне нужно было сделать вспомогательную функцию расширения представления, как бы она выглядела? Я действительно борюсь с синтаксисом при объединении дженериков и протоколов.