Skip to content

Commit

Permalink
MacOS support
Browse files Browse the repository at this point in the history
  • Loading branch information
diniska authored Nov 18, 2020
2 parents 28bc58f + b77a6f0 commit 13002a2
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ios.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Swift
name: iOS Build & Test

on:
push:
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: MacOS Build & Test

on:
push:
branches: [ void ]
pull_request:
branches: [ void ]

jobs:
build:

runs-on: macos-latest

steps:
- uses: actions/checkout@v2
- name: Selecting Xcode 12.2
run: sudo xcode-select --switch /Applications/Xcode_12.2.app
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import PackageDescription
let package = Package(
name: "SwiftUIPDF",
platforms: [
.iOS(.v9)
.iOS(.v9),
.macOS(.v10_15)
],
products: [
.library(
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SwiftUI PDF views

![Swift 5.3](https://img.shields.io/badge/Swift-5.3-FA5B2C) ![Xcode 12](https://img.shields.io/badge/Xcode-12-44B3F6) ![iOS 9.0](https://img.shields.io/badge/iOS-9.0-178DF6) ![iPadOS 9.0](https://img.shields.io/badge/iPadOS-9.0-178DF6) ![MacOS 10.15](https://img.shields.io/badge/MacOS-10.15-178DF6) ![iOS Tests](https://github.com/diniska/swiftui-pdf/workflows/iOS%20Build%20&%20Test/badge.svg) ![MacOS Tests](https://github.com/diniska/swiftui-pdf/workflows/MacOS%20Build%20&%20Test/badge.svg)

SwiftUI views collection to display PDF pages and files

* `PDFPageView` displays one pdf page
58 changes: 58 additions & 0 deletions Sources/SwiftUIPDF/AutoresizablePDFPageView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// AutoresizablePDFPageView.swift
//
//
// Created by Denis Chaschin on 18.11.2020.
//

#if canImport(PDFKit)

import PDFKit

/// A view that displays PDF page inside its bounds.
/// The PDF page automatically scales to fit the view
@available(iOS 11.0, macOS 10.4, *)
public final class AutoresizablePDFPageView: PlatformView {

private var pageSize: CGSize? {
didSet {
guard pageSize != oldValue else { return }
invalidateIntrinsicContentSize()
}
}

public var page: PDFPage? {
didSet {
pageSize = page?.bounds(for: .trimBox).size
setNeedsDisplay()
}
}

public override var frame: CGRect {
didSet {
setNeedsDisplay()
}
}

public override func draw(_ rect: CGRect) {
guard
let page = page,
let size = pageSize,
let context = CGContext.swiftuiPDF_currentContext
else { return }
let scale = bounds.size.width / size.width

context.scaleBy(x: scale, y: scale)
#if canImport(UIKit)
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1, y: -1)
#endif
page.draw(with: .trimBox, to: context)
}

public override var intrinsicContentSize: CGSize {
pageSize ?? .zero
}
}

#endif
38 changes: 38 additions & 0 deletions Sources/SwiftUIPDF/CrossplatformTypes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// CrossplatformTypes.swift
//
//
// Created by Denis Chaschin on 18.11.2020.
//

import CoreGraphics

#if canImport(UIKit)

import UIKit
public typealias PlatformView = UIView

extension CGContext {
static var swiftuiPDF_currentContext: CGContext? {
UIGraphicsGetCurrentContext()
}
}

#elseif canImport(AppKit)

import AppKit
public typealias PlatformView = NSView

extension NSView {
func setNeedsDisplay() {
setNeedsDisplay(bounds)
}
}

extension CGContext {
static var swiftuiPDF_currentContext: CGContext? {
NSGraphicsContext.current?.cgContext
}
}

#endif
40 changes: 40 additions & 0 deletions Sources/SwiftUIPDF/PDFPageView+AppKit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// PDFPageView+AppKit.swift
//
//
// Created by Denis Chaschin on 18.11.2020.
//

#if canImport(PDFKit) && canImport(AppKit) && canImport(SwiftUI) && canImport(Combine)

import AppKit
import SwiftUI
import PDFKit

/// A view that displays a single PDF page
@available(macOS 10.15, *)
extension PDFPageView: NSViewRepresentable {

public typealias NSViewType = AutoresizablePDFPageView

public func makeNSView(context: Context) -> NSViewType {
let view = NSViewType(frame: .zero)
view.layer?.backgroundColor = .clear
view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
view.setContentHuggingPriority(.defaultLow, for: .horizontal)
view.setContentHuggingPriority(.defaultLow, for: .vertical)
return view
}

public func updateNSView(_ pdfPageView: NSViewType, context: Context) {
pdfPageView.page = page
}

public static func dismantleNSView(_ pdfPageView: NSViewType, coordinator: ()) {
pdfPageView.page = nil
}

}

#endif
40 changes: 40 additions & 0 deletions Sources/SwiftUIPDF/PDFPageView+UIKit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// PDFPageView+UIKit.swift
//
//
// Created by Denis Chaschin on 17.10.2020.
//

#if canImport(PDFKit) && canImport(UIKit) && canImport(SwiftUI) && canImport(Combine)

import SwiftUI
import PDFKit
import UIKit

/// A view that displays a single PDF page
@available(iOS 13.0, *)
extension PDFPageView: UIViewRepresentable {

public typealias UIViewType = AutoresizablePDFPageView

public func makeUIView(context: Context) -> UIViewType {
let view = UIViewType(frame: .zero)
view.backgroundColor = .clear
view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
view.setContentHuggingPriority(.defaultLow, for: .horizontal)
view.setContentHuggingPriority(.defaultLow, for: .vertical)
return view
}

public func updateUIView(_ pdfPageView: UIViewType, context: Context) {
pdfPageView.page = page
}

public static func dismantleUIView(_ pdfPageView: UIViewType, coordinator: ()) {
pdfPageView.page = nil
}

}

#endif
93 changes: 12 additions & 81 deletions Sources/SwiftUIPDF/PDFPageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,103 +2,34 @@
// PDFPageView.swift
//
//
// Created by Denis Chaschin on 17.10.2020.
// Created by Denis Chaschin on 18.11.2020.
//

import UIKit

#if canImport(PDFKit)
import PDFKit

#if canImport(SwiftUI) && canImport(Combine)
import SwiftUI
#endif

/// A view that displays PDF page inside its bounds.
/// The PDF page automatically scales to fit the view
@available(iOS 11.0, *)
public final class AutoresizablePDFPageView: UIView {

private var pageSize: CGSize? {
didSet {
guard pageSize != oldValue else { return }
invalidateIntrinsicContentSize()
}
}

public var page: PDFPage? {
didSet {
pageSize = page?.bounds(for: .trimBox).size
setNeedsDisplay()
}
}

public override var frame: CGRect {
didSet {
setNeedsDisplay()
}
}

public override func draw(_ rect: CGRect) {
guard
let page = page,
let size = pageSize,
let context = UIGraphicsGetCurrentContext()
else { return }
let scale = bounds.size.width / size.width

context.scaleBy(x: scale, y: scale)
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1, y: -1)
page.draw(with: .trimBox, to: context)
}

public override var intrinsicContentSize: CGSize {
pageSize ?? .zero
}
}

#if canImport(SwiftUI) && canImport(Combine)

import SwiftUI
import PDFKit

/// A view that displays a single PDF page
@available(iOS 13.0, *)
public struct PDFPageView: UIViewRepresentable {
public typealias UIViewType = AutoresizablePDFPageView

@available(iOS 11.0, macOS 10.4, *)
public struct PDFPageView {
public var page: PDFPage?

public init(page: PDFPage? = nil) {
self.page = page
}

public func makeUIView(context: Context) -> UIViewType {
let view = UIViewType(frame: .zero)
view.backgroundColor = .clear
view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
view.setContentHuggingPriority(.defaultLow, for: .horizontal)
view.setContentHuggingPriority(.defaultLow, for: .vertical)
return view
}

public func updateUIView(_ pdfPageView: UIViewType, context: Context) {
pdfPageView.page = page
}

public static func dismantleUIView(_ pdfPageView: UIViewType, coordinator: ()) {
pdfPageView.page = nil
}

}

@available(iOS 13.0, *)
#if canImport(SwiftUI) && canImport(Combine)

import SwiftUI

@available(iOS 13.0, macOS 10.15, *)
struct PDFPageView_Previews: PreviewProvider {
static var previews: some View {
PDFPageView()
}
}

#endif
#endif
#endif // SwiftUI & Combine

#endif // PDFKit

0 comments on commit 13002a2

Please sign in to comment.