iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
Mobile Development

使用 SwiftUI 讓有趣的點子變成 Apps系列 第 27

D27 - 使用 SwiftUI 讓有趣的點子變成 Apps{無限猴子打字機: 把 log 輸出成 pdf}

  • 分享至 

  • xImage
  •  

原始的題目,是不斷的敲擊打字機,原來的思想實驗,是有「紙」這個要素的。所以加入輸出成 PDF 檔案的元素,如果想印出來,真的有機會了。

先在 log 區上方加一個按鈕,拿來輸出 pdf 檔。

private var monkeyLogsAndClearLogs: some View {
    HStack {
      Spacer()
      Text("打字紀錄")
      Button {
        // TODO: - 清掉打字
      } label: {
        Text("清除打字紀錄")
      }
      .padding(.leading, 20)
      .buttonStyle(.bordered)
      
      Button {
        // createPDFFile()
      } label: {
        Text("輸出 pdf")
      }
      .buttonStyle(.bordered)
      Spacer()
    }
  }

createPDFFile() 是之後才會實作,現在 UI 變成這樣。

https://ithelp.ithome.com.tw/upload/images/20220927/201406222CCvJFU3aH.png

接下來實作 createPDFFile()

extension InfiniteMonkeyTypingContentView {
  private func createPDFFile() {
    
    let outputFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("TypedStringLog.pdf")
    let title = "Your Title\n"
    var text = ""
    
    logs.forEach { log in
      text += "\n\(log.typedString)"
    }
    
    let titleAttributes = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 36)]
    let textAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12)]
    
    let formattedTitle = NSMutableAttributedString(string: title, attributes: titleAttributes)
    let formattedText = NSAttributedString(string: text, attributes: textAttributes)
    formattedTitle.append(formattedText)
    
    // 1. Create Print Formatter with your text.
    
    let formatter = UISimpleTextPrintFormatter(attributedText: formattedTitle)
    
    // 2. Add formatter with pageRender
    
    let render = UIPrintPageRenderer()
    render.addPrintFormatter(formatter, startingAtPageAt: 0)
    
    // 3. Assign paperRect and printableRect
    
    let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
    let printable = page.insetBy(dx: 0, dy: 0)
    
    render.setValue(NSValue(cgRect: page), forKey: "paperRect")
    render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
    
    // 4. Create PDF context and draw
    let rect = CGRect.zero
    
    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, rect, nil)
    
    for i in 1...render.numberOfPages {
      
      UIGraphicsBeginPDFPage();
      let bounds = UIGraphicsGetPDFContextBounds()
      render.drawPage(at: i - 1, in: bounds)
    }
    
    UIGraphicsEndPDFContext();
    
    // 5. Save PDF file
    
    do {
      try pdfData.write(to: outputFileURL, options: .atomic)
      
      print("wrote PDF file with multiple pages to: \(outputFileURL.path)")
    } catch {
      
      print("Could not create PDF file: \(error.localizedDescription)")
    }
  }
}

只要發動 createPDFFile() ,即使在模擬器,你也會得到一份 log 的 pdf 檔,我試跑了一下,pdf 會長這樣。

https://ithelp.ithome.com.tw/upload/images/20220927/20140622jRiIU9bV2e.png

https://ithelp.ithome.com.tw/upload/images/20220927/20140622U3QmvTN8uk.png


上一篇
D26 - 使用 SwiftUI 讓有趣的點子變成 Apps{無限猴子打字機: 讓猴子停手}
下一篇
D28 - 忒修斯之船 idea
系列文
使用 SwiftUI 讓有趣的點子變成 Apps30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言