PDFKit的scaleFactorForSizeToFit无法在SwiftUI中设置缩放(UIViewRepresentable)

js81xvg6  于 2022-12-26  发布在  Swift
关注(0)|答案(3)|浏览(159)

我正在开发一个使用PDFKit显示PDF的应用程序,我需要能够设置最小缩放级别-否则用户可以永远缩小。我尝试设置minScaleFactormaxScaleFactor,因为它们会关闭autoScales,所以我需要将scaleFactor设置为pdfView.scaleFactorForSizeToFit。然而,此设置不会产生与autoScales相同的起始缩放比例,尽管更改了实际的scaleFactor数值,起始缩放比例也不会更改。此照片是在autoScales打开时拍摄的:[![打开自动缩放的图像][1]][1]
当我使用scaleFactorForSizeToFit时会发生什么[![具有缩放因子的图像适合大小][2]][2]
要引用scaleFactorForSizeToFit的apple文档,请参阅
autoScales将用于缩放当前文档和版面的“大小适合”缩放因子。
我已经把我的代码贴在下面了。谢谢你的帮助。

import PDFKit
import SwiftUI
import Combine

class DataLoader : ObservableObject {
    @Published var data : Data?
    var cancellable : AnyCancellable?
    
    func loadUrl(url: URL) {
        cancellable = URLSession.shared.dataTaskPublisher(for: url)
            .map { $0.data }
            .receive(on: RunLoop.main)
            .sink(receiveCompletion: { (completion) in
                switch completion {
                case .failure(let failureType):
                    print(failureType)
                    //handle potential errors here
                case .finished:
                    break
                }
        }, receiveValue: { (data) in
            self.data = data
        })
    }
}

struct PDFSwiftUIView : View {
    @StateObject private var dataLoader = DataLoader()
    var StringToBeLoaded: String
    
    var body: some View {
        VStack {
            if let data = dataLoader.data {
                PDFRepresentedView(data: data)
                    .navigationBarHidden(false)
            } else {
                CustomProgressView()
                   //.navigationBarHidden(true)
            }
        }.onAppear {
            dataLoader.loadUrl(url: URL(string: StringToBeLoaded)!)
        }
    }
}

struct PDFRepresentedView: UIViewRepresentable {
    typealias UIViewType = PDFView
    
    let data: Data
    let singlePage: Bool = false
    
    func makeUIView(context _: UIViewRepresentableContext<PDFRepresentedView>) -> UIViewType {
        let pdfView = PDFView()
        
        
     
       // pdfView.autoScales = true
       // pdfView.maxScaleFactor = 0.1
      
        pdfView.minScaleFactor = 1
        pdfView.scaleFactor = pdfView.scaleFactorForSizeToFit
        pdfView.maxScaleFactor = 10
        
       
        if singlePage {
            pdfView.displayMode = .singlePage
        }
        return pdfView
    }
    
    func updateUIView(_ pdfView: UIViewType, context: UIViewRepresentableContext<PDFRepresentedView>) {
        pdfView.document = PDFDocument(data: data)
    }
    func canZoomIn() -> Bool {
           return false
       }
}

struct ContentV_Previews: PreviewProvider {
    static var previews: some View {
        PDFSwiftUIView(StringToBeLoaded: "EXAMPLE_STRING")
            .previewInterfaceOrientation(.portrait)
    }
}
6uxekuva

6uxekuva1#

也许这和顺序有关。这似乎对我有用:

pdfView.scaleFactor = pdfView.scaleFactorForSizeToFit
    pdfView.maxScaleFactor = 10.0
    pdfView.minScaleFactor = 1.0
    pdfView.autoScales = true
dffbzjpn

dffbzjpn2#

我最终解决了这个问题。下面的代码是我如何设法解决它的:

if let document = PDFDocument(data: data) {
               pdfView.displayDirection = .vertical
               pdfView.autoScales = true
               pdfView.document = document
               pdfView.setNeedsLayout()
               pdfView.layoutIfNeeded()
            pdfView.minScaleFactor = UIScreen.main.bounds.height * 0.00075
               pdfView.maxScaleFactor = 5.0
          
           }

由于某种原因,pdfView.scaleFactorForSizeToFit无法正常工作--它总是返回0。这可能是iOS 15的问题--我注意到在另一个答案中,其他人也有同样的问题。在上面的代码中,我所做的是我只是按屏幕高度缩放PDF以适应屏幕。这允许我或多或少地自己“自动缩放”。上面的代码正确地自动缩放PDF,并防止用户缩小太远。

xfb7svmp

xfb7svmp3#

最后一个解决方案是可行的,但你是一种硬编码的比例因子。所以它只适用于当页面高度总是相同的。请记住,macOS没有一个UISscreen,甚至在iPadOS下可以有几个窗口,窗口可以有一个不同的高度比屏幕高度与新的StageManager...这对我来说是有效的:

  • 首先,在几何读取器中 Package swiftUIView(在上面的示例中为PDFRepresentedView)。将视图高度(代理.大小.高度)传递到PDFRepresentedView中。
  • 在makeUIView中,设置

pdfView.最大比例因子=某个值〉1 pdfView.自动比例=真

  • 在updateUiView中,设置:
let pdfView = uiView
      if let pageHeight = pdfView.currentPage?.bounds(for: .mediaBox).height  {
         let scaleFactor:CGFloat = self.viewHeight / pageHeight
         pdfView.minScaleFactor = scaleFactor
      }

因为我的应用程序也支持macOS,所以我用同样的方法编写了一个NSViewRepresentable。编码愉快!

相关问题