Home > other >  How can I properly pass an array in iOS PDFKit
How can I properly pass an array in iOS PDFKit

Time:01-19

I'm trying to in an [string] array for a PDF. Below is what I have so far. I am guess I need to do a foreach somewhere, but I'm not entirely sure.

I thought something like this might work, but it does not.

       for entry in body {
        let attributedText = NSAttributedString(
            string: entry,
            attributes: textAttributes
        )
    }

private func addBody(body: [String], pageRect: CGRect, textTop: CGFloat) {
    let pageWidth = 8.5 * 72.0
    let pageHeight = 11 * 72.0
    let pageRect = CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)

    let bodyCG = addInstructor(instructor: "", pageRect: pageRect)
    let textFont = UIFont.systemFont(ofSize: 12.0, weight: .regular)

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .natural
    paragraphStyle.lineBreakMode = .byWordWrapping

    let textAttributes = [
      NSAttributedString.Key.paragraphStyle: paragraphStyle,
      NSAttributedString.Key.font: textFont
    ]

    let attributedText = NSAttributedString(
        string: body,
      attributes: textAttributes
    )

    let textRect = CGRect(
      x: 15,
      y: bodyCG   30,
      width: pageRect.width - 20,
      height: pageRect.height - textTop - pageRect.height / 5.0
    )
    attributedText.draw(in: textRect)
}

Adding some additional details. If I don't use [String] and just use String everything works fine. The PDF is generated, The concept I'm struggling to understand is how can I pass an array for the PDF.

var courseAttendees : [String] = ["name", "name", "name", "name"]

For Example, I want to pass courseAttendees and then loop through the array the names are just overlapped and shown below.

enter image description here

Final code.

private func addBody(body: [String], textTop: CGFloat) {
        let pageWidth = 8.5 * 72.0
        let pageHeight = 11 * 72.0
        let pageRect = CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)

        let bodyCG = addInstructor(instructor: "", pageRect: pageRect)
        let textFont = UIFont.systemFont(ofSize: 12.0, weight: .regular)

        let textAttributes: [NSAttributedString.Key: Any] =
          [NSAttributedString.Key.font: textFont]

        // keep track of the y position on the page. You might need
        // to set this globally as you have multiple pages
        var currentYPos: CGFloat = bodyCG

        // Loop through the array
         for entry in body {

             let attributedText = NSAttributedString(
                string: "\(entry)",
               attributes: textAttributes
             )

             // Update the currentYPos
             currentYPos  = 15

             // Use the currentYPos in the textRect
             let textRect = CGRect(
               x: 15,
               y: currentYPos,
               width: pageRect.width - 20,
               height: pageRect.height - textTop - pageRect.height / 5.0
             )
             attributedText.draw(in: textRect)
         }
    }

CodePudding user response:

Based on your question and image, I am assuming the PDF creation works fine but the data is not rendered as desired.

I think the two questions to answer here are:

  1. Where to loop through your array
  2. How to keep track of the current y coordinate in the page which is responsible for the vertical positioning

Here are some additions I made to try and fix your issue, I have added comments to what I have changed

// Somewhere appropriate in your code
var courseAttendees : [String] = ["name1", "name2", "name3", "name4"]

// Call the function, 15 is just a random number for textTop, 
// give it what you feel is appropriate
addBody(body: courseAttendees, textTop: 15)

// I have removed the pageRect parameter since you create it
// in the function
private func addBody(body: [String], textTop: CGFloat) {
    let pageWidth = 8.5 * 72.0
    let pageHeight = 11 * 72.0
    let pageRect = CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)

    let bodyCG = addInstructor(instructor: "", pageRect: pageRect)
    let textFont = UIFont.systemFont(ofSize: 12.0, weight: .regular)

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .natural
    paragraphStyle.lineBreakMode = .byWordWrapping

    let textAttributes = [
      NSAttributedString.Key.paragraphStyle: paragraphStyle,
      NSAttributedString.Key.font: textFont
    ]
    
    // keep track of the y position on the page. You might need
    // to set this globally as you have multiple pages
    var currentYPos: CGFloat = 0.0
    
    // Loop through the array
    for entry in body {
        
        let attributedText = NSAttributedString(
            string: entry,
          attributes: textAttributes
        )
        
        // Update the currentYPos
        currentYPos  = bodyCG   30

        // Use the currentYPos in the textRect
        let textRect = CGRect(
          x: 15,
          y: currentYPos,
          width: pageRect.width - 20,
          height: pageRect.height - textTop - pageRect.height / 5.0
        )
        attributedText.draw(in: textRect)
    }
}

I have not tested the above so please give this a try and check if it solves your issue.

If not, comment and I will update this accordingly.

  •  Tags:  
  • Related