Reputation: 8499
Using SwiftUI I try to design a View composed of a VideoPlayer on which I would like to apply a "dynamic" UIImageView for the videoOverlay:
, to simply the conception I use a png from my HD, but for real the UIImageView will come from an Observable shared object across all views
struct MyViewRepresentable: UIViewRepresentable {
typealias UIViewType = UIImageView
func updateUIView(_ uiView: UIImageView, context: Context) {
}
func makeUIView(context: Context) -> UIImageView {
let imageView = UIImageView()
imageView.image = UIImage(named: "tv-test-pattern.png")!
imageView.alpha = 0.3
return imageView
}
}
and I declare the player view as :
struct MyVideoPlayer: View {
//@ObservedObject var sharedData: SharedData
var body: some View {
var v = VideoPlayer(player: AVPlayer(url: URL(string: "https://myurltoanvideo.mp4")!), videoOverlay: {
GeometryReader { geometry in
MyViewRepresentable()
.frame(width: geometry.size.width, height: geometry.size.height)
.clipped()
}
})
v
}
}
For now I the png is replicated over the whole view (including back area around the active video) but I would like to have it constraint to the active video area, in a old app swift + uikit designer we used an "AV Player view Controller" component and in the Viewcontroler of the App, we manually added the UIImageView as a subview with several NSLayoutContraint.
Is there a way to reproduce that behavior using "SwiftUI only" code, or do I have to use a RepresentableView based on AVPlayerViewControler ?
thanks in advance for all advices
Upvotes: 1
Views: 25
Reputation: 30746
You can use @ObservedObject
inside your representable and updateUIView
will be called when the object changes. From there you can update the image, e.g.
struct MyViewRepresentable: UIViewRepresentable {
@ObservedObject var sharedData: SharedData
func updateUIView(_ uiView: UIImageView, context: Context) {
if imageView.image.name != sharedData.imageName {
imageView.image = UIImage(named: sharedData.imageName)!
}
}
func makeUIView(context: Context) -> UIImageView {
let imageView = UIImageView()
imageView.alpha = 0.3
return imageView
}
}
Maybe you could change from UIKit constraints to SwiftUI and then just use Image
? e.g.
struct MyVideoOverlay: View {
@ObservedObject var sharedData: SharedData
var body: some View {
// use alignment or stacks with spacers
Image(sharedData.imageName)
.alpha(0.3)
.frame( ...
}
}
Also if that SharedData
object is being passed down every View
it could be easier to use EnvironmentObject
so you can use it all Views without needing to pass it down as a let through ones that don't need it or to observe it.
Upvotes: 0