I successfully implemented PageView within SwiftUI via thread:
How to implement PageView in SwiftUI?
Passing in multiple Views via an Array works like a charm, as long as all views are of the same struct.PageView([TestView(), TestView()])
.
However, I'd like to pass in different views.PageView([TestView(), AnotherView(), DifferentView()])
.
All views are of SwiftUI type:struct NAME : View { code }
When I try to add different structs to an array I get the following error message:
var pageViewViewArray = [TestView(), AnotherView(), DifferentView()]
Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional.
Insert' as [Any]
By casting it to:
var pageViewViewArray = [TestView(), AnotherView(), DifferentView()] as! [Any]
PageView(pageViewViewArray)
PageView will say:
Protocol type 'Any' cannot conform to 'View' because only concrete types can conform to protocols
I'll greatly appreciate any ideas.
Try using type erasure by casting every view to AnyView
:
var pageViewViewArray: [AnyView] = [AnyView(TestView()), AnyView(AnotherView()), AnyView(DifferentView())]
Documentation here, and an example of using it here.
There is a more efficient way to do it, without type erasure. You should create a common view in which you inject an enum value based on which you then return a desired view. Take a look at an example below:
/// The first type of a view that accepts and shows a number
struct ViewA: View {
let number: Int
var body: some View {
Text("\(number)")
}
}
/// The second type of a view that accepts and shows a string
struct ViewB: View {
let string: String
var body: some View {
Text(string)
}
}
/// An enum type used for dependency injection
enum ViewType {
case viewA(number: Int)
case viewB(string: String)
}
/// A common view which internally handles different kind of views based on injected enum value
struct CommonView: View {
let viewType: ViewType
var body: some View {
switch viewType {
case .viewA(let number):
ViewA(number: number)
case .viewB(let string):
ViewB(string: string)
}
}
}
// Views used for page view controller, that are now of same type:
var pageViewViewArray = [
CommonView(viewType: .viewA(number: 1)),
CommonView(viewType: .viewB(string: "Hello, World!"))
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With