swiftuiview

update UIKit view when viewDidLayoutSubviewsCallback from swftUI wrapper gets call


Hello team i notice that we have a problem in our app that every time the user opens a Textfield the app freezes when the keyboard appears, this behavior was tracked down and it's a UI breaking design on a UIView

this view it's expandable and is original size is 80

when it gets expanded 206.33

this is the view code I change the colors to easy check the other's views created inside

private lazy var sharedUIPlaybackView: UIView = {
        let containerView = UIView().withAutoLayout()

        let propertySearchCriteria = PropertySearchCriteriaBuilder(hotelSearchParameters: viewModel.hotelSearchParameters).criteria
        var swiftUIView: SwiftUIView<LodgingPlaybackWrapper>! = nil
        swiftUIView = SwiftUIView(
            LodgingPlaybackWrapper(propertySearchCriteria: propertySearchCriteria,
                                   playbackUpdateNotificationSender: playbackUpdateNotificationSender,
                                   componentHandler: { [weak self] componentId in
                self?.componentReady(componentId)
            }),
            viewDidLayoutSubviewsCallback: { [weak self] in
                let extraPadding = self?.playbackViewExtraPadding ?? Spacing.spacing8x
                let newHeight = swiftUIView.frame.size.height + extraPadding
//                if newHeight != self?.sharedUIPlaybackViewHeightConstraint?.constant {
//                    self?.sharedUIPlaybackViewHeightConstraint?.constant = 206.33
//                }else {
//                    self?.sharedUIPlaybackViewHeightConstraint?.constant = 80
//                }
            }
        ).withAutoLayout().withAccessibilityIdentifier("test")

//        sharedUIPlaybackViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: 0)
//        sharedUIPlaybackViewHeightConstraint?.isActive = true
        containerView.backgroundColor = .blue
        swiftUIView.backgroundColor = .red

        containerView.addSubview(swiftUIView)
        containerView.addConstraints([
            swiftUIView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: playbackViewTopConstant),
            swiftUIView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: Spacing.spacing4x),
            swiftUIView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -Spacing.spacing4x),
            swiftUIView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -Spacing.spacing3x),
            swiftUIView.heightAnchor.constraint(equalToConstant: 206.33)
        ])
        return containerView
    }()

old devs created this function viewDidLayoutSubviewsCallback to connect user interaction on the wrapper and used on UIKit. this is the part where the math on the function gets weird and messed up the code by crashing the view

viewDidLayoutSubviewsCallback: { [weak self] in
                let extraPadding = self?.playbackViewExtraPadding ?? Spacing.spacing8x
                let newHeight = swiftUIView.frame.size.height + extraPadding
                if newHeight != self?.sharedUIPlaybackViewHeightConstraint?.constant {
                    self?.sharedUIPlaybackViewHeightConstraint?.constant = newHeight
                }
            }
        ).withAutoLayout().withAccessibilityIdentifier("test")

sharedUIPlaybackViewHeightConstraint = containerView.heightAnchor.constraint(equalToConstant: 0)
sharedUIPlaybackViewHeightConstraint?.isActive = true

I commented this math because is crashing the app and instead of giving a dynamical height I placed as a constant constraint as default height this is how I solved the problem of the UI, but I still need to update the view each time the user clicks and gets call by the method viewDidLayoutSubviewsCallback

what can I do?

I tried to add like a conditional on the method

if newHeight == 80 {
            containerView.addConstraints([
                swiftUIView.heightAnchor.constraint(equalToConstant: 80.0)
            ])
            containerView.layoutIfNeeded()
        }
        else {
            containerView.addConstraints([
                swiftUIView.heightAnchor.constraint(equalToConstant: 206.33)
            ])
            containerView.layoutIfNeeded()
        }

like this but it didn't work

this is how it looks with the constant value of 206.33

when it gets open looks good


Solution

  • this was solve with notification between framework for UI button click and app logic communication