How do you get the frame size in UIViewRepresentable?
I have a simple DrawView class that draw something and I would like to integrate with SwiftUI. This code works if I hardcode the frame size to 640x480, but is it possible to know the current frame size of ContentView?
struct ContentView: View {
var body: some View {
SwiftDrawView()
}
}
struct SwiftDrawView: UIViewRepresentable {
func makeUIView(context: Context) -> DrawView {
DrawView(frame:CGRect(x: 0, y: 0, width: 640, height: 480))
}
....
}
The Apple tutorial always use .zero and it won't work in this case.
By default SwiftUI's views take up only as much space as they need, but if you want that to change you can use a frame() modifier to tell SwiftUI what kind of size range you want to have. Note: if you want a view to go under the safe area, make sure you add the ignoresSafeArea() modifier.
The frame modifier allows you to provide the ideal size for the views that don't have content. SwiftUI uses ideal size only in conjunction with the fixedSize modifier. To learn more about the fixedSize modifier, take a look at my “The magic of fixed size modifier in SwiftUI” post.
Text("Hello, SwiftUI!") 1 Set . frame(maxWidth: . infinity) to make the text view expand to fill a container width.
All views have a natural position inside your hierarchy, but the offset() modifier lets you move them relative to that natural position. This is particularly useful inside ZStack , where it lets you control how views should overlap.
struct ContentView: View {
var body: some View {
GeometryReader { proxy in
SwiftDrawView(frame: proxy.frame(in: .local))
}
}
}
struct SwiftDrawView: UIViewRepresentable {
let frame: CGRect
func makeUIView(context: Context) -> DrawView {
DrawView(frame:frame)
}
....
}
The frame does not matter at UIView creation time (ie. in makeUIView), because constructed view will be resized according to final layout in container view and resulting frame will be passed in UIView.draw.
Here is complete example (Xcode 11.1) and Preview (Note: if you remove VStack in below example DrawView fills entire screen).
import SwiftUI
import UIKit
class DrawView : UIView {
override func draw(_ rect: CGRect) {
let path = UIBezierPath(ovalIn: rect)
UIColor.green.setFill()
path.fill()
}
}
struct SwiftDrawView: UIViewRepresentable {
typealias UIViewType = DrawView
func makeUIView(context: Context) -> DrawView {
DrawView()
}
func updateUIView(_ uiView: DrawView, context: UIViewRepresentableContext<SwiftDrawView>) {
// change here some DrawView properties if needed, eg. color
}
}
struct ContentView: View {
var body: some View {
VStack {
SwiftDrawView()
Text("SwiftUI native")
}
.edgesIgnoringSafeArea(.all)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
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