Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow working with Interface Builder #2

Open
alobaili opened this issue Jun 6, 2023 · 2 comments
Open

Allow working with Interface Builder #2

alobaili opened this issue Jun 6, 2023 · 2 comments

Comments

@alobaili
Copy link

alobaili commented Jun 6, 2023

Thanks for this brilliant solution.

It would be awesome if it can also work with view controllers that use Interface Builder. I tested this library on a view controller that have some IB outlets from an XIB and once I make the view controller a subclass of HostingParentController, all outlets become nil.

@GerdC
Copy link

GerdC commented Aug 8, 2023

@alobaili this code works for me with storyboard. Please test thoroughly and give feedback. (I also changed func viewWillLayoutSubviews() to open.)

open class HostingParentController: UIViewController {
    
    public var makeBackgroundsClear = true
    
    /// If the touches land on the base view of the HostingParentController, they will be forwarded to this view if it is not nil.
    public var forwardBaseTouchesTo: UIView?
    
    /// If the touches land on the bottom of a SwiftUI scroll container (*not* the content), pass through these touches to the UIKit layer underneath.
    public var ignoreTouchesOnSwiftUIScrollView = false
    
    override open func loadView() {
        if isLoadedFromStoryboard {
            super.loadView()  // Load the view from the storyboard
        } else {
            let capturer = HostingParentView()
            view = capturer
        }
    }
    
    private var isLoadedFromStoryboard: Bool {
        return storyboard != nil
    }
    
    private func wrapOriginalViewWithHostingParentView() {
        let originalView = self.view!
        
        let capturer = HostingParentView(frame: originalView.frame)
        self.view = capturer
        
        capturer.addSubview(originalView)
        originalView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            originalView.topAnchor.constraint(equalTo: capturer.topAnchor),
            originalView.bottomAnchor.constraint(equalTo: capturer.bottomAnchor),
            originalView.leadingAnchor.constraint(equalTo: capturer.leadingAnchor),
            originalView.trailingAnchor.constraint(equalTo: capturer.trailingAnchor)
        ])
    }

    open override func viewDidLoad() {
        super.viewDidLoad()

        // Only wrap the view if loaded from a storyboard
        if isLoadedFromStoryboard {
            wrapOriginalViewWithHostingParentView()
        }
    }
    
    open override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        
        if let capturer = view as? HostingParentView {
            capturer.makeBackgroundsClear = makeBackgroundsClear
            capturer.forwardBaseTouchesTo = forwardBaseTouchesTo
            capturer.ignoreTouchesOnSwiftUIScrollView = ignoreTouchesOnSwiftUIScrollView
        }
    }
}

@GerdC
Copy link

GerdC commented Aug 15, 2023

Using the code above intensely for a few days now and it is absolutely stable for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants