Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - Inserting image onto PDF no longer working on iOS 13

Currently working on a feature to export a PDF on my loan calculator app. I have a preview screen that'll show the PDF before you save it. The preview screen composes of a webView with html that contain placeholders. I was able to successfully insert an image onto the correct placeholder and have it display onto the PDF. But with iOS 13, the image no longer shows or it displays too small.

LineGraph.html

<div class ="line-graph">
    <center class = "graph-header">Amortization Line Chart</center>
    <img class = "image" src="data:image/png;base64,#ImageData#" alt="Line Graph">
</div>

Code that converts the image to Base-64 encoded string and place it in #ImageData#

let isLineGraphSelected = lineGraphDictionary[.isSelectedString] as! Bool
self.lineGraphSnapshot = lineGraphDictionary[.snapshotString] as? UIImage
    if isLineGraphSelected && self.lineGraphSnapshot != nil{
        let data = self.lineGraphSnapshot.pngData()
        if let imageITData = data?.base64EncodedString() {
            LineGraphHTMLContent = LineGraphHTMLContent.replacingOccurrences(of: "#ImageData#", with: imageITData)
                    }
                } else {
                    LineGraphHTMLContent = ""
                }

Let me know if you need more context.

Screenshots:

iOS 12.1

enter image description here

iOS 13.0

enter image description here


Here's my other HTML files for full context

PDFSheet.HTML

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
            <style>
            .loan-box {
                max-width: 800px;
                margin: auto;
                padding: 30px;
                border: 1px solid #d9d9d9;
                font-size: 16px;
                line-height: 24px;
                font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
                color: #555;
            }
            .graph-header {
                margin: auto;
                font-size: 45px;
                line-height: 45px;
                padding: 30px;
                font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
                font-weight: 300;
                color: #333;
            }
            .line-graph {
                max-width: 800px;
                margin: auto;
                padding: 30px;
            }
            .loan-box table {
                width: 100%;
                line-height: inherit;
                text-align: left;
            }

            .loan-box table td {
                padding: 5px;
                vertical-align: top;
            }

            .loan-box table tr td:nth-child(2) {
                text-align: right;
            }

            .loan-box table tr.top table td {
                padding-bottom: 20px;
                width: 100%;
                display: block;
                text-align: center;
            }

            .loan-box table tr.top table td.title {
                font-size: 45px;
                line-height: 45px;
                color: #333;
            }
            .loan-box table tr.top table td.date {
                font-size: 24px;
            }
            .loan-box table tr.heading td {
                background: #eee;
                border-bottom: 1px solid #ddd;
                font-weight: bold;
            }

            .loan-box table tr.item td{
                border-bottom: 1px solid #eee;
            }

            .loan-box table tr.item.last td {
                padding-bottom: 20px;
                border-bottom: none;
            }

            .loan-box table tr.item.last.results td{
                font-weight: bold;
            }
            .line-graph img {
                display: block;
                max-width: 800px;
                width: auto;
                height: auto;
            }

            * RTL *
            .rtl {
                direction: rtl;
                font-family: Tahoma, 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
            }

            .rtl table {
                text-align: right;
            }

            .rtl table tr td:nth-child(2) {
                text-align: left;
            }
            </style>
    </head>

    <body>
        #RESULTS#
        #LINE_GRAPH#
    </body>
</html>

Results.HTML

<div class="loan-box">
    <table cellpadding="0" cellspacing="0">
        <tr class="top">
            <td colspan="2">
                <table>
                    <tr>
                        <td class="title">
                            #LOAN_NAME#
                        </td>

                        <td class="date">
                            #DATE_CREATED#
                        </td>
                    </tr>
                </table>
            </td>
        </tr>

        <tr class="heading">
            <td>
                Loan information
            </td>

            <td></td>
        </tr>

        <tr class="item">
            <td>
                Loan amount
            </td>

            <td>
                #LOAN_AMOUNT#
            </td>
        </tr>

        <tr class="item">
            <td>
                Interest rate
            </td>

            <td>
                #INTEREST_RATE#
            </td>
        </tr>

        <tr class="item">
            <td>
                Number of payments
            </td>

            <td>
                #NUM_OF_PAYMENTS#
            </td>
        </tr>

        <tr class="item">
            <td>
                Extra payments
            </td>

            <td>
                #EXTRA_PAYMENTS#
            </td>
        </tr>

        <tr class="item last">
            <td>
                Estimated payoff date
            </td>

            <td>
                #PAYOFF_DATE#
            </td>
        </tr>

        <tr class="heading">
            <td>
                Results
            </td>

            <td></td>
        </tr>

        <tr class="item">
            <td>
                Monthly Payments
            </td>

            <td>
                #MONTHLY_PAYMENTS#
            </td>
        </tr>

        <tr class="item">
            <td>
                Total interest
            </td>

            <td>
                #TOTAL_INTEREST#
            </td>
        </tr>

        <tr class="item">
            <td>
                Interest Savings
            </td>

            <td>
                #INTEREST_SAVINGS#
            </td>
        </tr>
        <tr class="item">
            <td>
                Time saved
            </td>

            <td>
                #TIME_SAVED#
            </td>
        </tr>
        <tr class="item last results">
            <td>
                Total loan amount
            </td>

            <td>
                #TOTAL_LOAN#
            </td>
        </tr>
    </table>
</div>

It also can be possible that the function I used to capture the image was affected in iOS 13. I noticed that when I increase the width of the image to a crazy amount in my CSS, the image was very low res. This makes me think that the image being generated is very small in iOS 13. Why? I have no godly idea.

func takeScreenshot() -> UIImage {

        // Begin context
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)

        // Draw view in that context
        drawHierarchy(in: self.bounds, afterScreenUpdates: true)

        // And finally, get image
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        if (image != nil)
        {
            return image!
        }
        return UIImage()
    }

New Discovery

I believe the issue is in the takeScreenshot function above. I printed out the image variable and this is what I found.

iOS 12

Optional(<UIImage: 0x6000016fc070> size {575.33333333333337, 350} orientation 0 scale 3.000000)

iOS 13

Optional(<UIImage:0x6000013637b0 anonymous {575.33333333333337, 350}>)

Why did size got replaced with anonymous and why are orientation and scale missing? If I can answer this then I can solve this annoying issue.


Solved

I found the issue. My solution is posted below.

like image 785
Daniel Espina Avatar asked Oct 16 '22 10:10

Daniel Espina


2 Answers

To solve this issue you can add/assign height and with using two way, One is, assign height and width in line-graph class OR second assign height and width by percentage(%) or pixel(px) in an inline-style method in <div> tag see the following code.

<style>
div.line-graph {
 width:100px;
  height:100%;  
}
</style>

OR

<div class ="line-graph" style="height:100px; width:100%; background:#ffffff">
    <center class = "graph-header">Amortization Line Chart</center>
    <img class = "image" src="data:image/png;base64,#ImageData#" alt="Line Graph">
</div>
like image 75
AtulParmar Avatar answered Oct 19 '22 00:10

AtulParmar


I solved the problem.

I replaced drawHierarchy with draw.

func takeScreenshot() -> UIImage {

    // Begin context
    print(UIScreen.main.scale)
    print(self.bounds.size)
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)

    // Draw view in that context
    draw(self.bounds) //drawHierarchy(in: self.bounds, afterScreenUpdates: true)
    // And finally, get image
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    print(image)
    if (image != nil)
    {
        return image!
    }
    return UIImage()
}

I am not entirely sure why that worked so if anyone could enlighten me that'll be great.

like image 20
Daniel Espina Avatar answered Oct 18 '22 23:10

Daniel Espina