UIViewControllerRepresentable嵌套的UIScrollView容器内视图动画/过渡失效问题求助
UIViewControllerRepresentable嵌套的UIScrollView容器内视图动画/过渡失效问题求助
大家好,我最近尝试用UIViewControllerRepresentable封装了一个UIScrollView,想做一个自定义的SwiftUI滚动容器,但遇到了一个头疼的问题:当我把带过渡动画的视图嵌入这个容器里时,它们的动画完全不生效了!但同样的视图放在容器外面时,动画表现完全正常。
下面是我的测试代码,麻烦大家帮忙看看哪里出问题了?
测试视图代码
struct Demo: View { class ViewModel: ObservableObject { @Published var option1: Bool = false @Published var option3: Bool = false } @StateObject private var viewModel = ViewModel() @State private var option2: Bool = false @State private var option4: Bool = false var body: some View { VStack { VStack { Text("In Scroll Container") UIScrollContainer { VStack(spacing: 0) { VStack { Toggle("ViewModel Option 1", isOn: $viewModel.option1.animation()) if viewModel.option1 { Text("Option 1 is ON") .padding(.vertical, 20) } } .padding() .background(.black.opacity(0.1)) VStack { Toggle("Option 2", isOn: $option2.animation()) if option2 { Text("Option 2 is ON") .padding(.vertical, 20) } } .padding() .background(.black.opacity(0.2)) } } } .background(.red.opacity(0.2)) .frame(maxHeight: .infinity) VStack(spacing: 0) { Text("Without Container") VStack { Toggle("ViewModel Option 3", isOn: $viewModel.option3.animation()) if viewModel.option3 { Text("Option 3 is ON") .padding(.vertical, 20) } } .padding() .background(.black.opacity(0.1)) VStack { Toggle("Option 4", isOn: $option4.animation()) if option4 { Text("Option 4 is ON") .padding(.vertical, 20) } } .padding() .background(.black.opacity(0.2)) Spacer() } .background(.yellow.opacity(0.2)) .frame(maxHeight: .infinity) } } }
自定义滚动容器代码
struct UIScrollContainer<Content: View>: UIViewControllerRepresentable { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIViewController(context: Context) -> UIViewController { let scrollViewVC = UIViewController() scrollViewVC.view.backgroundColor = .clear let scrollView = UIScrollView() scrollView.backgroundColor = .clear let contentVC = UIHostingController(rootView: self.content) contentVC.sizingOptions = .intrinsicContentSize contentVC.view.backgroundColor = .clear contentVC.safeAreaRegions = [] context.coordinator.contentVC = contentVC context.coordinator.scrollView = scrollView scrollView.delegate = context.coordinator scrollView.translatesAutoresizingMaskIntoConstraints = false scrollViewVC.view.addSubview(scrollView) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: scrollViewVC.view.topAnchor), scrollView.bottomAnchor.constraint(equalTo: scrollViewVC.view.bottomAnchor), scrollView.leadingAnchor.constraint(equalTo: scrollViewVC.view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: scrollViewVC.view.trailingAnchor) ]) contentVC.willMove(toParent: scrollViewVC) scrollViewVC.addChild(contentVC) contentVC.view.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(contentVC.view) NSLayoutConstraint.activate([ contentVC.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor), contentVC.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor), contentVC.view.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor), contentVC.view.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor), contentVC.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor) ]) contentVC.didMove(toParent: scrollViewVC) return scrollViewVC } func updateUIViewController(_ uiViewController: UIViewController, context: Context) { withTransaction(context.transaction) { context.coordinator.contentVC?.rootView = content } } func makeCoordinator() -> Coordinator { return Coordinator() } class Coordinator: NSObject, UIScrollViewDelegate { var contentVC: UIHostingController<Content>? var scrollView: UIScrollView? } }
我试过在updateUIViewController里用withTransaction来传递动画事务,但好像没起作用。有没有大佬能指点一下,这个自定义容器哪里没处理好,导致内部视图的动画失效了?
内容来源于stack exchange
相关产品推荐
相关产品推荐

