'How to calculate dynamic height of UIViewControllerRepresentable
I am working on a SwiftUI project, I need to display MarkDownContent which is coming from api. (MarkDownContent can contain text, image url, list etc..)
I am using third party SDK Marky-Mark to render the Markdown String.
I am using UIViewControllerRepresentable to display the Markdown String.
As, I need to pass some height to the MarkDownView() to display the markdown contents.
My problem is, how can i calculate the height of UIViewControllerRepresentable markdown contents to display the data
My Code is
struct MarkDownView: UIViewControllerRepresentable {
@Binding var dynamicHeight: CGFloat
func makeUIViewController(context: Context) -> MarkDownViewController {
let markDownVC = MarkDownViewController()
return markDownVC
}
func updateUIViewController(_ uiViewController: MarkDownViewController, context: Context) {}
class MarkDownViewController: UIViewController {
var scrollView = UIScrollView()
var markDownView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
scrollView.isScrollEnabled = false
scrollView.backgroundColor = UIColor.yellow
view.addSubview(scrollView)
markDownView = getMarkDownView()
scrollView.addSubview(markDownView!)
let views: [String: Any] = [
"view": view,
"scrollView": scrollView,
"markDownView": markDownView
]
scrollView.translatesAutoresizingMaskIntoConstraints = false
markDownView?.translatesAutoresizingMaskIntoConstraints = false
var constraints: [NSLayoutConstraint] = []
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView]|", options: [], metrics: [:], views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: [], metrics: [:], views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[markDownView(==scrollView)]|", options: [], metrics: [:], views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[markDownView]|", options: [], metrics: [:], views: views)
view.addConstraints(constraints)
view.layoutIfNeeded()
}
}
private extension MarkDownViewController {
func getMarkDownView() -> UIView {
// Parsing to MarkDownItem's
let markDownString = getMarkDownString()
let markyMark = MarkyMark(build: {
// Choose flavor (set of rules)
$0.setFlavor(ContentfulFlavor())
//Example: Add single custom rules
//$0.addRule(CustomHeaderRule())
})
let markDownItems = markyMark.parseMarkDown(markDownString)
// Configure styling, see README for more styling options or Implement your own Styling object instead of DefaultStyling.
let styling = DefaultStyling()
styling.listStyling.bulletColor = UIColor.red
styling.imageStyling.contentInsets = UIEdgeInsets(top: 10, left: 20, bottom: 10, right: 20)
styling.paragraphStyling.baseFont = UIFont.italicSystemFont(ofSize: 30)
styling.headingStyling.contentInsetsForLevels = [
UIEdgeInsets(top: 16, left: 6, bottom: 15, right: 10), // H1
UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 10) // H2, ...
]
styling.headingStyling.textColorsForLevels = [
.red, // H1
.black, // H2
.gray // H3, ...
]
// Only uppercase H1 headers
styling.headingStyling.capitalizationForLevels = [
.uppercased, // H1
nil //H2, ...
]
styling.linkStyling.textColor = UIColor.green
let configuration = MarkdownToViewConverterConfiguration(styling: styling)
let converter = MarkDownConverter(configuration: configuration)
// Converter hook, only meant for very specific (otherwise impossible) usecases. The hook is triggered every time a MarkdownItem is converted to a view.
// In this example the headers are rotated, which is normally not supported in MarkyMark styling.
converter.didConvertElement = {
markdownItem, view in
}
return converter.convert(markDownItems)
}
func getMarkDownString() -> String {
var markdownString: String = ""
if let filepath = Bundle.main.path(forResource: "hello", ofType: "md") {
markdownString = try! String(contentsOfFile: filepath)
}
return markdownString
}
SwiftUI Code
struct ContentView: View {
@State private var height: CGFloat = .zero
var body: some View {
ScrollView {
VStack {
MarkDownView(dynamicHeight: $height)
// .frame(height:1500)
}
}
.ignoresSafeArea()
}
}
In MarkDownViewController class, in UIScrollView I am adding Markdown view to show it as scrollable content
For testing purpose i have passed height of Markdown View hardcoded, but it should be dynamic as the content of MarkDown View will be different.
I need to pass height of MarkDownViewController from UIViewRepresentable to SwiftUI View using @Bindings
How can i calculate the height of UIViewRepresentable ? Please help me with this
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
