Last active
November 9, 2022 17:00
-
-
Save macguru/1163a27af6db71ae905bab0f58295474 to your computer and use it in GitHub Desktop.
Adapter view to use a (wrapping) SwiftUI view with auto layout, where a certain width is pre-defined
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
public final class SwiftUIView<Content: View>: UIView { | |
private let hostingController: UIHostingController<Content> | |
public init(rootView: Content) { | |
hostingController = UIHostingController(rootView: rootView) | |
super.init(frame: .zero) | |
let hostedView = hostingController.view | |
addSubview(hostedView) | |
hostedView.translatesAutoresizingMaskIntoConstraints = false | |
NSLayoutConstraint.activate([ | |
hostedView.leadingAnchor.constraint(equalTo: leadingAnchor), | |
hostedView.trailingAnchor.constraint(equalTo: trailingAnchor), | |
hostedView.topAnchor.constraint(equalTo: topAnchor), | |
hostedView.bottomAnchor.constraint(equalTo: bottomAnchor) | |
]) | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
public override var frame: NSRect { | |
didSet { | |
if frame.width != oldValue.width { | |
let constrainedSize = CGSize(width: frame.width, height: .infinity) | |
let fittingSize = hostingController.sizeThatFits(in: constrainedSize) | |
intrinsicContentHeight = fittingSize.height | |
} | |
} | |
} | |
private var intrinsicContentHeight: CGFloat = UIView.noIntrinsicMetric { | |
didSet { | |
if intrinsicContentHeight != oldValue { | |
invalidateIntrinsicContentSize() | |
} | |
} | |
} | |
public override var intrinsicContentSize: NSSize { | |
CGSize(width: UIView.noIntrinsicMetric, height: intrinsicContentHeight) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
UIKit classes (
UIView
,UIHostingController
) can be replaced by AppKit classes (NSView
,NSHostingController
), code works there as well.Instantly pre-computing the
intrinsicContentSize
seems to perform better on dynamic changes of the height. Whereas observing the view's layouted size (as Tunous' SwiftUIView.swift) or using above approach with a layout constraint show small delays in updating themselves.