ios – The way to take away the shadow when utilizing UISheetPresentationController?

0
28
ios – The way to take away the shadow when utilizing UISheetPresentationController?


I am at the moment writing a customized backside sheet to make use of in SwiftUI which makes use of UISheetPresentationController. I’ve created a struct that conforms to UIViewRepresentable. Within the updateUIView methodology, I am wrapping a SwiftUI view in a UIHostingController then presenting the view controller as a sheet.

func updateUIView(_ uiView: UIView, context: Context) {
    let viewController = UIViewController()
    
    let hostingController = UIHostingController(rootView: content material)

    viewController.addChild(hostingController)
    viewController.view.addSubview(hostingController.view)
    
    hostingController.view.backgroundColor = .clear
    hostingController.view.translatesAutoresizingMaskIntoConstraints = false
    
    viewController.view.backgroundColor = .clear
    viewController.view.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        hostingController.view.topAnchor.constraint(equalTo: viewController.view.topAnchor, constant: 20),
        hostingController.view.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor, constant: 20),
        hostingController.view.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor, constant: -20),
        hostingController.view.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor, constant: -20)
    ])
    
    hostingController.didMove(toParent: viewController)

    if let sheetController = viewController.presentationController as? UISheetPresentationController {
        sheetController.detents = detents
        sheetController.largestUndimmedDetentIdentifier = .massive
        sheetController.prefersScrollingExpandsWhenScrolledToEdge = false
        sheetController.prefersEdgeAttachedInCompactHeight = true
        sheetController.widthFollowsPreferredContentSizeWhenEdgeAttached = true
    }
    
    viewController.presentationController?.delegate = context.coordinator
    
    if isPresented {
        uiView.window?.rootViewController?.current(viewController, animated: true)
    } else {
        uiView.window?.rootViewController?.dismiss(animated: true)
    }
}

I’ve modified the code in order that the sheet has a transparent background in order that the SwiftUI view appears to be like prefer it’s floating.

Image of sheet

Nevertheless, whenever you begin to swipe down on the sheet you begin to see the shadow from the sheet.

Image of the issue

As you possibly can see there’s a clear dividing line the place there’s an additional shadow onto of the dimmed background.

I’ve seemed by means of the view hierarchy and it seems to not be associated to the internet hosting controller or the view controller. I’ve tried adjusting properties comparable to layer.shadowColor on the sheetController however most of these properties are nil. Does anybody know take away the shadow or another appropriate work round for it?

EDIT: The minimal reproducible instance.

struct SheetPresentationForSwiftUI: UIViewRepresentable the place Content material: View {
    @Binding var isPresented: Bool
    let onDismiss: (() -> Void)?
    let detents: [UISheetPresentationController.Detent]
    let content material: Content material
    
    init(
        _ isPresented: Binding,
        onDismiss: (() -> Void)? = nil,
        detents: [UISheetPresentationController.Detent] = [.medium()],
        @ViewBuilder content material: () -> Content material
    ) {
        self._isPresented = isPresented
        self.onDismiss = onDismiss
        self.detents = detents
        self.content material = content material()
    }
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        let viewController = UIViewController()
        
        let hostingController = UIHostingController(rootView: content material)

        viewController.addChild(hostingController)
        viewController.view.addSubview(hostingController.view)
        
        hostingController.view.backgroundColor = .clear
        hostingController.view.translatesAutoresizingMaskIntoConstraints = false
        
        viewController.view.backgroundColor = .clear
        viewController.view.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            hostingController.view.topAnchor.constraint(equalTo: viewController.view.topAnchor),
            hostingController.view.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor),
            hostingController.view.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor),
            hostingController.view.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor)
        ])
        
        hostingController.didMove(toParent: viewController)
        hostingController.view.sizeToFit()

        if let sheetController = viewController.presentationController as? UISheetPresentationController {
            sheetController.detents = [.medium()]
            sheetController.largestUndimmedDetentIdentifier = .massive
            sheetController.prefersGrabberVisible = true
            sheetController.prefersScrollingExpandsWhenScrolledToEdge = false
            sheetController.prefersEdgeAttachedInCompactHeight = true
            sheetController.widthFollowsPreferredContentSizeWhenEdgeAttached = true
        }
        
        viewController.presentationController?.delegate = context.coordinator
        
        if isPresented {
            uiView.window?.rootViewController?.current(viewController, animated: true)
        } else {
            uiView.window?.rootViewController?.dismiss(animated: true)
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(isPresented: $isPresented, onDismiss: onDismiss)
    }
    
    class Coordinator: NSObject, UISheetPresentationControllerDelegate {
        @Binding var isPresented: Bool
        let onDismiss: (() -> Void)?
        
        init(isPresented: Binding, onDismiss: (() -> Void)? = nil) {
            self._isPresented = isPresented
            self.onDismiss = onDismiss
        }
        
        func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
            isPresented = false
            if let onDismiss = onDismiss {
                onDismiss()
            }
        }
        
    }
    
}

struct SheetWithDetentsViewModifier: ViewModifier the place SwiftUIContent: View {
    
    @Binding var isPresented: Bool
    let onDismiss: (() -> Void)?
    let detents: [UISheetPresentationController.Detent]
    let swiftUIContent: SwiftUIContent
    
    init(isPresented: Binding, detents: [UISheetPresentationController.Detent] = [.medium()] , onDismiss: (() -> Void)? = nil, content material: () -> SwiftUIContent) {
        self._isPresented = isPresented
        self.onDismiss = onDismiss
        self.swiftUIContent = content material()
        self.detents = detents
    }
    
    func physique(content material: Content material) -> some View {
        ZStack {
            SheetPresentationForSwiftUI($isPresented,onDismiss: onDismiss, detents: detents) {
                swiftUIContent
            }
            .fixedSize()
            content material
        }
    }
}

extension View {
    func sheetWithDetents(
        isPresented: Binding,
        detents: [UISheetPresentationController.Detent] = [.medium()],
        onDismiss: (() -> Void)? = nil,
        content material: @escaping () -> Content material) -> some View the place Content material : View {
            modifier(
                SheetWithDetentsViewModifier(
                    isPresented: isPresented,
                    detents: detents,
                    onDismiss: onDismiss,
                    content material: content material)
            )
        }
}

struct TestView: View {
    @State var showSheet = false
    
    var physique: some View {
        NavigationStack {
            VStack {
                Textual content("Faucet me")
                    .onTapGesture {
                        showSheet = true
                    }
            }
        }.sheetWithDetents(isPresented: $showSheet) {
            Textual content("Hey")
                .body(maxWidth: .infinity, maxHeight: .infinity)
                .padding()
                .background(
                    RoundedRectangle(cornerRadius: 40)
                        .fill(Materials.regularMaterial)
                        
                ).padding()
        }
    }
}

#Preview {
    TestView()
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here