如何解决iOS 14上的SwiftUI / UIKit自省
我有一个使用UIViewRepresentable
并查看自省以在SwiftUI应用程序中为ScrollView
创建提拉刷新功能的应用程序,该应用程序可在iOS 13中使用。但是,iOS 14破坏了它,并且我不知道该如何解决。这是实现:
import SwiftUI
import Introspect
private struct PullToRefresh: UIViewRepresentable {
@Binding var isShowing: Bool
let onRefresh: () -> Void
public init(
isShowing: Binding<Bool>,onRefresh: @escaping () -> Void
) {
_isShowing = isShowing
self.onRefresh = onRefresh
}
public class Coordinator {
let onRefresh: () -> Void
let isShowing: Binding<Bool>
init(
onRefresh: @escaping () -> Void,isShowing: Binding<Bool>
) {
self.onRefresh = onRefresh
self.isShowing = isShowing
}
@objc
func onValueChanged() {
isShowing.wrappedValue = true
onRefresh()
}
}
public func makeUIView(context: UIViewRepresentableContext<PullToRefresh>) -> UIView {
let view = UIView(frame: .zero)
view.isHidden = true
view.isUserInteractionEnabled = false
return view
}
private func tableView(entry: UIView) -> UIScrollView? {
// Search in ancestors - FAILS HERE
if let tableView = Introspect.findAncestor(ofType: UIScrollView.self,from: entry) {
return tableView
}
guard let viewHost = Introspect.findViewHost(from: entry) else {
return nil
}
// Search in siblings - FAILS HERE
return Introspect.previousSibling(containing: UIScrollView.self,from: viewHost)
}
public func updateUIView(_ uiView: UIView,context: UIViewRepresentableContext<PullToRefresh>) {
DispatchQueue.main.asyncAfter(deadline: .now()) {
guard let tableView = self.tableView(entry: uiView) else {
return
}
if let refreshControl = tableView.refreshControl {
if self.isShowing {
refreshControl.beginRefreshing()
} else {
refreshControl.endRefreshing()
}
return
}
let refreshControl = UIRefreshControl()
refreshControl.addTarget(context.coordinator,action: #selector(Coordinator.onValueChanged),for: .valueChanged)
tableView.refreshControl = refreshControl
}
}
public func makeCoordinator() -> Coordinator {
return Coordinator(onRefresh: onRefresh,isShowing: $isShowing)
}
}
extension View {
public func pullToRefresh(isShowing: Binding<Bool>,onRefresh: @escaping () -> Void) -> some View {
return overlay(
PullToRefresh(isShowing: isShowing,onRefresh: onRefresh)
.frame(width: 0,height: 0),alignment: .center)
}
}
此代码与this repository略有修改。
这是用法的粗略版本:
NavigationView {
VStack(alignment: .center) {
...
GeometryReader { geometry in
ScrollView(.vertical) {
...
}
.pullToRefresh(isShowing: self.$refreshingEvents,onRefresh: refreshEvents)
}
}.navigationBarTitle("Events",displayMode: .inline)
}
使用此功能时,ScrollView
没有附加刷新指示器。将pullToRefresh
移动到ScrollView
的子视图不会改变任何内容。这是自省的结果:
PlatformViewHost<PlatformViewRepresentableAdaptor<PullToRefresh>>
_UIHostingView<ModifiedContent<Element,StyleContextWriter<SidebarStyleContext>>>
UIViewControllerWrapperView
UINavigationTransitionView
UILayoutContainerView
_UIPanelControllerContentView
_UISplitViewControllerPanelImplView
PlatformViewHost<PlatformViewControllerRepresentableAdaptor<MulticolumnSplitViewRepresentable<Element,Never,_UnaryViewAdaptor<EmptyView>>>>
_UIHostingView<_ViewList_View>
UIViewControllerWrapperView
UITransitionView
UILayoutContainerView
PlatformViewHost<PlatformViewControllerRepresentableAdaptor<UIKitTabView>>
_UIHostingView<ModifiedContent<MainView,_EnvironmentKeyWritingModifier<Optional<UserData>>>>
UIDropShadowView
UITransitionView
UIWindow
那里应该有一个UIScrollView
,但是在iOS 14上没有。{p1}有没有办法我可以修复当前代码或使用保留相同功能的替代方法对其进行更新? >
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。