@@ -7,6 +7,9 @@ struct RepositoryReadmeView: View {
7
7
`README.md` file and how to implement a custom `OpenURLAction` that
8
8
scrolls to the corresponding heading when the user taps on an anchor
9
9
link.
10
+
11
+ Additionally, it shows how to use an `ImageRenderer` to render the `README.md`
12
+ file into a PDF.
10
13
"""
11
14
12
15
@State private var owner = " apple "
@@ -59,24 +62,33 @@ private struct ReadmeView: View {
59
62
} else {
60
63
ScrollViewReader { proxy in
61
64
ScrollView {
62
- Group {
63
- if let response, let content = response. decodedContent {
64
- Markdown ( content, baseURL: response. baseURL, imageBaseURL: response. imageBaseURL)
65
- } else {
66
- Markdown ( " Oops! Something went wrong while fetching the README file. " )
67
- }
68
- }
69
- . padding ( )
70
- . background ( Theme . gitHub. textBackgroundColor)
71
- . markdownTheme ( . gitHub)
72
- . scrollToMarkdownHeadings ( using: proxy)
65
+ content
66
+ . scrollToMarkdownHeadings ( using: proxy)
73
67
}
74
68
}
75
69
}
76
70
}
77
71
. onAppear {
78
72
self . loadContent ( )
79
73
}
74
+ . toolbar {
75
+ if !self . isLoading {
76
+ ShareLink ( item: self . renderPDF ( ) )
77
+ }
78
+ }
79
+ }
80
+
81
+ private var content : some View {
82
+ Group {
83
+ if let response, let content = response. decodedContent {
84
+ Markdown ( content, baseURL: response. baseURL, imageBaseURL: response. imageBaseURL)
85
+ } else {
86
+ Markdown ( " Oops! Something went wrong while fetching the README file. " )
87
+ }
88
+ }
89
+ . padding ( )
90
+ . background ( Theme . gitHub. textBackgroundColor)
91
+ . markdownTheme ( . gitHub)
80
92
}
81
93
82
94
private func loadContent( ) {
@@ -86,6 +98,26 @@ private struct ReadmeView: View {
86
98
self . isLoading = false
87
99
}
88
100
}
101
+
102
+ @MainActor private func renderPDF( ) -> URL {
103
+ let url = URL . documentsDirectory. appending ( path: " README.pdf " )
104
+ let renderer = ImageRenderer ( content: self . content. padding ( ) )
105
+ renderer. proposedSize = . init( width: UIScreen . main. bounds. width, height: nil )
106
+
107
+ renderer. render { size, render in
108
+ var mediaBox = CGRect ( origin: . zero, size: size)
109
+ guard let context = CGContext ( url as CFURL , mediaBox: & mediaBox, nil ) else {
110
+ return
111
+ }
112
+
113
+ context. beginPDFPage ( nil )
114
+ render ( context)
115
+ context. endPDFPage ( )
116
+ context. closePDF ( )
117
+ }
118
+
119
+ return url
120
+ }
89
121
}
90
122
91
123
// MARK: - Heading anchor scrolling
0 commit comments