Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI frame size

Tags:

swift

swiftui

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.

like image 626
Lim Thye Chean Avatar asked Jun 17 '19 05:06

Lim Thye Chean


People also ask

How do I find my SwiftUI frame size?

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.

What is SwiftUI frame?

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.

How do I make text full width in SwiftUI?

Text("Hello, SwiftUI!") 1 Set . frame(maxWidth: . infinity) to make the text view expand to fill a container width.

What is offset in SwiftUI?

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.


2 Answers

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)
    }
    ....
}
like image 194
Victor Kushnerov Avatar answered Sep 21 '22 12:09

Victor Kushnerov


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).

Drawing in UIViewRepresentable

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()
    }
}
like image 40
Asperi Avatar answered Sep 22 '22 12:09

Asperi