Cannot see my Text with making a PDF in macOs in iOS is works

66 views Asked by At

I have made a func that's makes me a pdf. In IOs it works perfectly fine. In macOs it looks that is works but the text is not visible. De column stroke is visible but the text not..

I have tried everything, but I cannot find a solution.

My iOS code is:

    func createInvoiceRental(rentalOrderId: String, baseDocument: PDFDocument, rentalData: RentalDataInfo) -> Data? {
        guard let page = baseDocument.page(at: 0) else {
            return nil
        }
        
        let pdfMetaData = [
            kCGPDFContextCreator: "BOX",
            kCGPDFContextAuthor: "BOX",
            kCGPDFContextTitle: "Verhuur Factuur"
        ]
        
        let format = UIGraphicsPDFRendererFormat()
        format.documentInfo = pdfMetaData as [String: Any]
        
        let pageBounds = page.bounds(for: .mediaBox)
        let pageWidth = pageBounds.width
//        let pageHeight = pageBounds.height
        //    let pageRect = CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)
        
        let renderer = UIGraphicsPDFRenderer(bounds: pageBounds)
        
        let data = renderer.pdfData { (context) in
            context.beginPage()
            
            if let cgPage = baseDocument.page(at: 0)?.pageRef {
                let ctx = context.cgContext
                
                // Flip de context om de Y-as om te keren
                ctx.translateBy(x: 0, y: pageBounds.height)
                ctx.scaleBy(x: 1.0, y: -1.0)
                
                // Teken de basis PDF-pagina
                ctx.drawPDFPage(cgPage)
                
                // Herstel de context transformatie
                ctx.translateBy(x: 0, y: pageBounds.height)
                ctx.scaleBy(x: 1.0, y: -1.0)
            }
            
            let attributes = [
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12)
            ]
            
            let attributesLittle = [
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10)
            ]
            
            let attributesBold = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12)
            ]
            
            let attributesBoldTotal = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)
            ]
            
            let attributesCustomerInfo = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)
            ]
            
            let attributesFactuurnummer = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20)
            ]
            
            let paragraphStyleHeader = NSMutableParagraphStyle()
            paragraphStyleHeader.alignment = .center // Centreren voor headers
            let attributesHeader = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12),
                NSAttributedString.Key.paragraphStyle: paragraphStyleHeader
            ]
            
            let headerAttributes = [
                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12)
            ]
//
//            let boxssInfoStyle = NSMutableParagraphStyle()
//            boxssInfoStyle.alignment = .center
//            let attributesBoxssInfo = [
//                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12),
//                NSAttributedString.Key.paragraphStyle: boxssInfoStyle
//            ]
            
            let customerInfo = "\(rentalData.customerInfo.customerFirstName)\(rentalData.customerInfo.customerMiddelName) \(rentalData.customerInfo.customerLastName) \n\(rentalData.customerInfo.addressStreetNamePickUp) \(rentalData.customerInfo.addressHouseNumberPickUp)\n\(rentalData.customerInfo.addressZipCodePickUp) \(rentalData.customerInfo.addressPlaceNamePickUp)\nNederland"
            let attributedCustomerInfo = NSAttributedString(string: customerInfo, attributes: attributesCustomerInfo)
            let textRectCustomerInfo = CGRect(x: 20, y: 150, width: pageWidth - 40, height: 100)
            attributedCustomerInfo.draw(in: textRectCustomerInfo)
            
            // Factuurinformatie
            let invoiceInfo = "Factuurdatum: \(DateFormats.ins.shortDateFormatter.string(from: rentalData.orderInfo.statusDate))\nFactuurnummer: Nog Maken\nRelatienummer: \(rentalData.customerInfo.customerNumber)\nBetaalconditie: Binnen 14 dagen\nVervaldatum: Nog maken"
            let attributedInvoiceInfo = NSAttributedString(string: invoiceInfo, attributes: attributes)
            let textRectInvoiceInfo = CGRect(x: 380, y: 150, width: pageWidth - 400, height: 100)
            attributedInvoiceInfo.draw(in: textRectInvoiceInfo)
            
            //Factuurnummer
            let factuurnummer = "Factuurnummer: 00000000"
            let attributedFactuurnummer = NSAttributedString(string: factuurnummer, attributes: attributesFactuurnummer)
            let textRectFactuurnummer = CGRect(x: 20, y: 260, width: pageWidth - 40, height: 100)
            attributedFactuurnummer.draw(in: textRectFactuurnummer)

            // Stel de breedtes van de kolommen in
            let totalAvailableWidth = pageWidth - 40 // Trek de marges af
            let firstColumnWidth = totalAvailableWidth * 0.4 // 40% voor de eerste kolom
            let otherColumnWidth = (totalAvailableWidth - firstColumnWidth) / 4 // Verdeel de resterende 60% over de andere 4 kolommen

            let rowHeight: CGFloat = 20.0
            let headerYPos: CGFloat = 310
            let itemStartYPos = headerYPos + rowHeight

            // Koppen
            let headers = ["", "Aantallen", "Prijs Ex", "BTW", "Prijs Incl"]
            for (index, header) in headers.enumerated() {
                let xPos = index == 0 ? 20 : (20 + firstColumnWidth + CGFloat(index - 1) * otherColumnWidth)
                let columnWidth = index == 0 ? firstColumnWidth : otherColumnWidth
                let rect = CGRect(x: xPos, y: headerYPos, width: columnWidth, height: rowHeight)

                // Bereken de verticale offset voor de header
                let headerSize = header.size(withAttributes: attributesHeader)
                let headerYPosAdjusted = headerYPos + (rowHeight - headerSize.height) / 2

                // Pas de tekst rect aan voor de header
                let headerRect = CGRect(x: xPos + 5, y: headerYPosAdjusted, width: columnWidth, height: headerSize.height)

                let attributedHeader = NSAttributedString(string: header, attributes: attributesBold)
                attributedHeader.draw(in: headerRect)
            }

            // Orderitems
            let numberOfRows = rentalData.orderItems.count
            for row in 0..<numberOfRows {
                let yPos = itemStartYPos + (rowHeight * CGFloat(row))
                let item = rentalData.orderItems[row]
                
                let BTW = item.rentalRentPriceIncl - item.rentalRentPriceEx
                
                let columns = [item.rentalName, "\(item.rentalPieces)", "\(NumberFormats.ins.currency(item.rentalRentPriceEx))", "\(NumberFormats.ins.currency(BTW))", "\(NumberFormats.ins.currency(item.rentalRentPriceIncl))"]
                
                for (columnIndex, columnText) in columns.enumerated() {
                    let xPos = columnIndex == 0 ? 20 : (20 + firstColumnWidth + CGFloat(columnIndex - 1) * otherColumnWidth)
                    let columnWidth = columnIndex == 0 ? firstColumnWidth : otherColumnWidth
                    let rect = CGRect(x: xPos, y: yPos, width: columnWidth, height: rowHeight)
                    let textSize = columnText.size(withAttributes: attributes)
                    let textYPos = yPos + (rowHeight - textSize.height) / 2
                    let textRect = CGRect(x: xPos + 5, y: textYPos, width: columnWidth - 10, height: textSize.height)
                    let attributedString = NSAttributedString(string: columnText, attributes: attributes)
                    attributedString.draw(in: textRect)
                    let lineRect = CGRect(x: 20, y: yPos + rowHeight, width: pageWidth - 40, height: 1)
                        context.stroke(lineRect)
                }
            }

            // Totaalrij
            let totalYPos = itemStartYPos + (rowHeight * CGFloat(numberOfRows))
            
            let BTW = rentalData.orderInfo.revenueTotalIncl - rentalData.orderInfo.revenueTotalEx
            let totalColumns = ["Totaal", "", String(NumberFormats.ins.currency(rentalData.orderInfo.revenueTotalEx)), String(NumberFormats.ins.currency(BTW)), String(NumberFormats.ins.currency(rentalData.orderInfo.revenueTotalIncl))]
            for (index, total) in totalColumns.enumerated() {
                let xPos = index == 0 ? 20 : (20 + firstColumnWidth + CGFloat(index - 1) * otherColumnWidth)
                let columnWidth = index == 0 ? firstColumnWidth : otherColumnWidth
                let rect = CGRect(x: xPos, y: totalYPos, width: columnWidth, height: rowHeight)
                // Bereken de verticale offset voor de totalen
                let totalSize = total.size(withAttributes: attributesBold)
                let totalYPosAdjusted = totalYPos + (rowHeight - totalSize.height) / 2

                // Pas de tekst rect aan voor de totalen met een marge
                let totalRect = CGRect(x: xPos + 5, y: totalYPosAdjusted, width: columnWidth - 10, height: totalSize.height)

                let attributedTotal = NSAttributedString(string: total, attributes: attributesBoldTotal)
                attributedTotal.draw(in: totalRect)
            }
            
            let additionalTextYPos = totalYPos + 30 // 20 punten onder de laatste rij
            let additionalText = "Het totaal bedrag van  \(NumberFormats.ins.currency(rentalData.orderInfo.revenueTotalIncl)) dient binnen 14 dagen op het rekeningnummer NL57INGB0009080522 te zijn bijgeschreven onder vermelding van uw factuurnummer (!!!nog maken!!!) en relatienummer (\(rentalData.customerInfo.customerNumber))."
            let attributedAdditionalText = NSAttributedString(string: additionalText, attributes: attributesLittle)
            let additionalTextRect = CGRect(x: 20, y: additionalTextYPos, width: pageWidth - 40, height: 60) // Hoogte aangepast naar behoefte
            attributedAdditionalText.draw(in: additionalTextRect)
            
            //BOXSS Info

            let boxssInfoHeader = "Adresgegevens:"
            let boxssInfoContent = "\nLandweerstraat-zuid 140\n5349 AK, Oss"
            let attributedBoxssInfoHeader = NSAttributedString(string: boxssInfoHeader, attributes: headerAttributes)
            let attributedBoxssInfoContent = NSAttributedString(string: boxssInfoContent, attributes: attributes)
            let textRectBoxssInfoHeader = CGRect(x: 20, y: 770, width: pageWidth - 40, height: 20)
            let textRectBoxssInfoContent = CGRect(x: 20, y: 775, width: pageWidth - 40, height: 80)
            attributedBoxssInfoHeader.draw(in: textRectBoxssInfoHeader)
            attributedBoxssInfoContent.draw(in: textRectBoxssInfoContent)

            let boxssInfo2Header = "Contact Gegevens:"
            let boxssInfo2Content = "\nTel: 0880157700\nEmail: [email protected]\nKVK: 17203644"
            let attributedBoxssInfo2Header = NSAttributedString(string: boxssInfo2Header, attributes: headerAttributes)
            let attributedBoxssInfo2Content = NSAttributedString(string: boxssInfo2Content, attributes: attributes)
            let textRectBoxssInfo2Header = CGRect(x: 240, y: 770, width: pageWidth - 260, height: 20)
            let textRectBoxssInfo2Content = CGRect(x: 240, y: 775, width: pageWidth - 260, height: 80)
            attributedBoxssInfo2Header.draw(in: textRectBoxssInfo2Header)
            attributedBoxssInfo2Content.draw(in: textRectBoxssInfo2Content)

            let boxssInfo3Header = "Betaal Gegevens:"
            let boxssInfo3Content = "\nBOXSS Verhuurt\nNL57INGB0009080522\nBTW: NL817971166B01"
            let attributedBoxssInfo3Header = NSAttributedString(string: boxssInfo3Header, attributes: headerAttributes)
            let attributedBoxssInfo3Content = NSAttributedString(string: boxssInfo3Content, attributes: attributes)
            let textRectBoxssInfo3Header = CGRect(x: 440, y: 770, width: pageWidth - 460, height: 20)
            let textRectBoxssInfo3Content = CGRect(x: 440, y: 775, width: pageWidth - 460, height: 80)
            attributedBoxssInfo3Header.draw(in: textRectBoxssInfo3Header)
            attributedBoxssInfo3Content.draw(in: textRectBoxssInfo3Content)
        }
        
        return data
    }

My macOs code:

    func createInvoiceRental(rentalOrderId: String, baseDocument: PDFDocument, rentalData: RentalDataInfo) -> Data? {
        guard let page = baseDocument.page(at: 0) else {
            return nil
        }

        let pdfMetaData = [
            kCGPDFContextCreator as String: "BOX",
            kCGPDFContextAuthor as String: "BOX",
            kCGPDFContextTitle as String: "Verhuur Factuur"
        ]

        let pageBounds = page.bounds(for: .mediaBox)
        let pdfData = NSMutableData()
        guard let pdfConsumer = CGDataConsumer(data: pdfData as CFMutableData) else { return nil }

        var mediaBox = pageBounds
        guard let pdfContext = CGContext(consumer: pdfConsumer, mediaBox: &mediaBox, pdfMetaData as CFDictionary?) else { return nil }
        
        let ctx = pdfContext

        let pageWidth = pageBounds.width

        pdfContext.beginPDFPage(nil)

        if let cgPage = baseDocument.page(at: 0)?.pageRef {
            let ctx = pdfContext

            ctx.drawPDFPage(cgPage)
        }
        
        ctx.saveGState()
            
        let attributes = [
            NSAttributedString.Key.font: NSFont.systemFont(ofSize: 12),
            NSAttributedString.Key.foregroundColor: NSColor.black
        ]


        let attributesLittle = [
            NSAttributedString.Key.font: NSFont.systemFont(ofSize: 10)
        ]

        let attributesBold = [
            NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 12)
        ]

        let attributesBoldTotal = [
            NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 14)
        ]

        let attributesCustomerInfo = [
            NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 15)
        ]

        let attributesFactuurnummer = [
            NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 20)
        ]
        
        let headerAttributes = [
            NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 12)
        ]
        
        let paragraphStyleHeader = NSMutableParagraphStyle()
        paragraphStyleHeader.alignment = .center

        let attributesHeader = [
            NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 12),
            NSAttributedString.Key.paragraphStyle: paragraphStyleHeader
        ]
//
//            let boxssInfoStyle = NSMutableParagraphStyle()
//            boxssInfoStyle.alignment = .center
//            let attributesBoxssInfo = [
//                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12),
//                NSAttributedString.Key.paragraphStyle: boxssInfoStyle
//            ]
        
        let customerInfo = "\(rentalData.customerInfo.customerFirstName)\(rentalData.customerInfo.customerMiddelName) \(rentalData.customerInfo.customerLastName) \n\(rentalData.customerInfo.addressStreetNamePickUp) \(rentalData.customerInfo.addressHouseNumberPickUp)\n\(rentalData.customerInfo.addressZipCodePickUp) \(rentalData.customerInfo.addressPlaceNamePickUp)\nNederland"
        let attributedCustomerInfo = NSAttributedString(string: customerInfo, attributes: attributesCustomerInfo)
        let textRectCustomerInfo = CGRect(x: 20, y: 20, width: pageWidth - 40, height: 100)
        attributedCustomerInfo.draw(in: textRectCustomerInfo)
        
        // Factuurinformatie
        let invoiceInfo = "Factuurdatum: \(DateFormats.ins.shortDateFormatter.string(from: rentalData.orderInfo.statusDate))\nFactuurnummer: Nog Maken\nRelatienummer: \(rentalData.customerInfo.customerNumber)\nBetaalconditie: Binnen 14 dagen\nVervaldatum: Nog maken"
        let attributedInvoiceInfo = NSAttributedString(string: invoiceInfo, attributes: attributes)
        let textRectInvoiceInfo = CGRect(x: 380, y: 150, width: pageWidth - 400, height: 100)
        attributedInvoiceInfo.draw(in: textRectInvoiceInfo)
        
        //Factuurnummer
        let factuurnummer = "Factuurnummer: 00000000"
        let attributedFactuurnummer = NSAttributedString(string: factuurnummer, attributes: attributesFactuurnummer)
        let textRectFactuurnummer = CGRect(x: 20, y: 260, width: pageWidth - 40, height: 100)
        attributedFactuurnummer.draw(in: textRectFactuurnummer)

        // Stel de breedtes van de kolommen in
        let totalAvailableWidth = pageWidth - 40 // Trek de marges af
        let firstColumnWidth = totalAvailableWidth * 0.4 // 40% voor de eerste kolom
        let otherColumnWidth = (totalAvailableWidth - firstColumnWidth) / 4 // Verdeel de resterende 60% over de andere 4 kolommen

        let rowHeight: CGFloat = 20.0
        let headerYPos: CGFloat = 310
        let itemStartYPos = headerYPos + rowHeight

        // Koppen
        let headers = ["", "Aantallen", "Prijs Ex", "BTW", "Prijs Incl"]
        for (index, header) in headers.enumerated() {
            let xPos = index == 0 ? 20 : (20 + firstColumnWidth + CGFloat(index - 1) * otherColumnWidth)
            let columnWidth = index == 0 ? firstColumnWidth : otherColumnWidth

            // Bereken de verticale offset voor de header
            let headerSize = header.size(withAttributes: attributesHeader)
            let headerYPosAdjusted = headerYPos + (rowHeight - headerSize.height) / 2

            // Pas de tekst rect aan voor de header
            let headerRect = CGRect(x: xPos + 5, y: headerYPosAdjusted, width: columnWidth, height: headerSize.height)

            let attributedHeader = NSAttributedString(string: header, attributes: attributesBold)
            attributedHeader.draw(in: headerRect)
        }

        // Orderitems
        let numberOfRows = rentalData.orderItems.count
        for row in 0..<numberOfRows {
            let yPos = itemStartYPos + (rowHeight * CGFloat(row))
            let item = rentalData.orderItems[row]
            
            let BTW = item.rentalRentPriceIncl - item.rentalRentPriceEx
            
            let columns = [item.rentalName, "\(item.rentalPieces)", "\(NumberFormats.ins.currency(item.rentalRentPriceEx))", "\(NumberFormats.ins.currency(BTW))", "\(NumberFormats.ins.currency(item.rentalRentPriceIncl))"]
            
            print(item.rentalName)
            
            for (columnIndex, columnText) in columns.enumerated() {
                let xPos = columnIndex == 0 ? 20 : (20 + firstColumnWidth + CGFloat(columnIndex - 1) * otherColumnWidth)
                let columnWidth = columnIndex == 0 ? firstColumnWidth : otherColumnWidth
                let textSize = columnText.size(withAttributes: attributes)
                let textYPos = yPos + (rowHeight - textSize.height) / 2
                let textRect = CGRect(x: xPos + 5, y: textYPos, width: columnWidth - 10, height: textSize.height)
                let attributedString = NSAttributedString(string: columnText, attributes: attributes)
                attributedString.draw(in: textRect)
                let lineRect = CGRect(x: 20, y: yPos + rowHeight, width: pageWidth - 40, height: 1)
                ctx.stroke(lineRect)
            }
        }

        // Totaalrij
        let totalYPos = itemStartYPos + (rowHeight * CGFloat(numberOfRows))
        
        let BTW = rentalData.orderInfo.revenueTotalIncl - rentalData.orderInfo.revenueTotalEx
        let totalColumns = ["Totaal", "", String(NumberFormats.ins.currency(rentalData.orderInfo.revenueTotalEx)), String(NumberFormats.ins.currency(BTW)), String(NumberFormats.ins.currency(rentalData.orderInfo.revenueTotalIncl))]
        for (index, total) in totalColumns.enumerated() {
            let xPos = index == 0 ? 20 : (20 + firstColumnWidth + CGFloat(index - 1) * otherColumnWidth)
            let columnWidth = index == 0 ? firstColumnWidth : otherColumnWidth
            // Bereken de verticale offset voor de totalen
            let totalSize = total.size(withAttributes: attributesBold)
            let totalYPosAdjusted = totalYPos + (rowHeight - totalSize.height) / 2

            // Pas de tekst rect aan voor de totalen met een marge
            let totalRect = CGRect(x: xPos + 5, y: totalYPosAdjusted, width: columnWidth - 10, height: totalSize.height)

            let attributedTotal = NSAttributedString(string: total, attributes: attributesBoldTotal)
            attributedTotal.draw(in: totalRect)
        }
        
        let additionalTextYPos = totalYPos + 30 // 20 punten onder de laatste rij
        let additionalText = "Het totaal bedrag van  \(NumberFormats.ins.currency(rentalData.orderInfo.revenueTotalIncl)) dient binnen 14 dagen op het rekeningnummer  te zijn bijgeschreven onder vermelding van uw factuurnummer (!!!nog maken!!!) en relatienummer (\(rentalData.customerInfo.customerNumber))."
        let attributedAdditionalText = NSAttributedString(string: additionalText, attributes: attributesLittle)
        let additionalTextRect = CGRect(x: 20, y: additionalTextYPos, width: pageWidth - 40, height: 60) // Hoogte aangepast naar behoefte
        attributedAdditionalText.draw(in: additionalTextRect)
        
        //BOXSS Info

        let boxssInfoHeader = "Adresgegevens:"
        let boxssInfoContent = "\n140"
        let attributedBoxssInfoHeader = NSAttributedString(string: boxssInfoHeader, attributes: headerAttributes)
        let attributedBoxssInfoContent = NSAttributedString(string: boxssInfoContent, attributes: attributes)
        let textRectBoxssInfoHeader = CGRect(x: 20, y: 770, width: pageWidth - 40, height: 20)
        let textRectBoxssInfoContent = CGRect(x: 20, y: 775, width: pageWidth - 40, height: 80)
        attributedBoxssInfoHeader.draw(in: textRectBoxssInfoHeader)
        attributedBoxssInfoContent.draw(in: textRectBoxssInfoContent)

        let boxssInfo2Header = "Contact Gegevens:"
        let boxssInfo2Content = "\nTel: \nEmail: .nl\nKVK: "
        let attributedBoxssInfo2Header = NSAttributedString(string: boxssInfo2Header, attributes: headerAttributes)
        let attributedBoxssInfo2Content = NSAttributedString(string: boxssInfo2Content, attributes: attributes)
        let textRectBoxssInfo2Header = CGRect(x: 240, y: 770, width: pageWidth - 260, height: 20)
        let textRectBoxssInfo2Content = CGRect(x: 240, y: 775, width: pageWidth - 260, height: 80)
        attributedBoxssInfo2Header.draw(in: textRectBoxssInfo2Header)
        attributedBoxssInfo2Content.draw(in: textRectBoxssInfo2Content)

        let boxssInfo3Header = "Betaal Gegevens:"
        let boxssInfo3Content = "\nBOX\nNL57\nBTW: NL"
        let attributedBoxssInfo3Header = NSAttributedString(string: boxssInfo3Header, attributes: headerAttributes)
        let attributedBoxssInfo3Content = NSAttributedString(string: boxssInfo3Content, attributes: attributes)
        let textRectBoxssInfo3Header = CGRect(x: 440, y: 770, width: pageWidth - 460, height: 20)
        let textRectBoxssInfo3Content = CGRect(x: 440, y: 775, width: pageWidth - 460, height: 80)
        attributedBoxssInfo3Header.draw(in: textRectBoxssInfo3Header)
        attributedBoxssInfo3Content.draw(in: textRectBoxssInfo3Content)
        
        ctx.restoreGState()
        
        pdfContext.endPDFPage()

        // Sluit de PDF-context
        pdfContext.closePDF()

        return pdfData as Data
    }

I have tried multiple differente way's but none are working. Also I have ask chatGPT and found no answer.

0

There are 0 answers