如何使自定义 UIViewRepresentable 填充其父 VStack 并使自定义子视图居中?

问题描述 投票:0回答:1

所以我的项目中有以下内容。

  1. ContentView ~ 包含 3 个 vstack。
  2. CustomView ~ 具有固定大小 300x300 的 containerView 的自定义视图,应始终位于 ContentView 的中心
  3. CustomViewRepresentable ~ UIViewRepresentable,以便将 CustomView 插入 ContentView。

每个的代码如下:

内容视图

import SwiftUI
import UIKit

struct ContentView: View {
    
    var body: some View {
        VStack(alignment: .center, spacing: 0) {
            VStack {
                Color.blue
                    .frame(height: 50)
            }
            VStack {
                HStack {
                    Color.green
                        .frame(height: 100)
                    Text("Text")
                    Color.green
                        .frame(height: 100)
                }
            }
            VStack { // content view
                GeometryReader { geometry in
                    VStack {
                        CustomViewRepresentable()
                            .frame(width: geometry.size.width, height: geometry.size.height)
                            .background(.gray)
                            .border(.red, width: 1)
                    }
                    .frame(width: geometry.size.width, height: geometry.size.height)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

自定义视图

import UIKit

class CustomView: UIView {
    private let containerView = UIView()
    override func layoutSubviews() {
        containerView.center = self.center
    }

    func addContainerView() {
        containerView.frame = CGRect(origin: .zero, size: CGSize(width: 300, height: 300))
        addSubview(containerView)
        containerView.center = self.center
    }
}

自定义视图可表示

import UIKit
import SwiftUI

struct CustomViewRepresentable: UIViewRepresentable {
    typealias UIViewType = CustomView
    
    func makeUIView(context: Context) -> CustomView {
        let customView = CustomView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
        customView.addContainerView()
        return customView
    }

    func updateUIView(_ uiView: CustomView, context: Context) {
        
    }
}

我面临的问题是 CustomView 中的 containerView 不会显示,除非我使用可表示内部的框架初始化 CustomView。

func makeUIView(context: Context) -> CustomView {
        let customView = CustomView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))

我不明白为什么需要这样做,因为我希望 CustomView 获取它嵌入的 VStack 的完整宽度和高度。因此我认为只要这样做

CustomViewRepresentable()
   .frame(width: geometry.size.width, height: geometry.size.height)

VStack 内部应该可以正常工作,但显然不行。那么,让

CustomViewRepresentable
填充其父级同时保持
containerView
始终居中的最佳方式是什么?

swift swiftui uiview uiviewrepresentable
1个回答
0
投票

无需在

CustomView
函数中提供
func makeUIView(context: Context) -> CustomView
框架。将
let customView = CustomView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
代码替换为
let customView = CustomView()
后,在我这边工作。请使用下面的代码检查。

内容查看

import SwiftUI
import UIKit

struct ContentView: View {
    
    var body: some View {
        VStack(alignment: .center, spacing: 0) {
            VStack {
                Color.blue
                    .frame(height: 50)
            }
            VStack {
                HStack {
                    Color.green
                        .frame(height: 100)
                    Text("Text")
                    Color.green
                        .frame(height: 100)
                }
            }
            VStack { // content view
                GeometryReader { geometry in
                    VStack {
                        CustomViewRepresentable()
                            .background(.gray)
                            .border(.red, width: 1)
                    }
                    .frame(width: geometry.size.width, height: geometry.size.height)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

自定义视图

import UIKit

class CustomView: UIView {
    private let containerView = UIView()
    override func layoutSubviews() {
        containerView.center = self.center
    }

    func addContainerView() {
        containerView.frame = CGRect(origin: .zero, size: CGSize(width: 300, height: 300))
        addSubview(containerView)
        containerView.center = self.center
    }
}

自定义视图可表示

import UIKit
import SwiftUI

struct CustomViewRepresentable: UIViewRepresentable {
    typealias UIViewType = CustomView
    
    func makeUIView(context: Context) -> CustomView {
        let customView = CustomView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
        customView.addContainerView()
        return customView
    }

    func updateUIView(_ uiView: CustomView, context: Context) {
        
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.