【问题标题】:SwiftUI print a viewSwiftUI 打印视图
【发布时间】:2020-03-03 23:52:58
【问题描述】:

我有一个使用 UIKit 和 Objective C 的旧 iOS 应用程序,我目前正在将其移植到 SwiftUI 和 Swift。一切都很顺利,我喜欢 Swift 和 SwiftUI。该应用程序几乎完成了,但该应用程序依赖于用户能够打印和/或将主视图保存为 PDF。我只是不知道如何在 swiftui 中访问视图以将其转换为 PDF。这是我现有/工作的 Objective-c 代码。

- (IBAction)actionPrint:(id)sender {
    // CREATE CLEAR BACKGROUND
    [legMain setBackgroundColor:[UIColor clearColor]];

    // SCROLL TO BASE POSITION
    [legMain scrollRectToVisible:CGRectMake(1, 1, 1, 1) animated:NO];

    // RESET ZOOM
    SnapPanel *myObject = [self fGetObject];
    myObject.zoom = [NSNumber numberWithDouble:1.0];
    [self fSave];

    // RECORD FRAME SIZE AND SET TO CONTENT SIZE
    double dWidth = legMain.frame.size.width;
    double dHeight = legMain.frame.size.height;
    [legMain setFrame:CGRectMake(legMain.frame.origin.x, legMain.frame.origin.y, legMain.contentSize.width, legMain.contentSize.height)];

    // GET VIEW AS NSDATA FOR PDF
    NSMutableData *pdfData = [NSMutableData data];
    CGRect pageSize = CGRectMake(0.0, 0.0, 8.5 * 72.0, 11.0 * 72.0);
    UIGraphicsBeginPDFContextToData(pdfData, pageSize, nil);
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();

    // CREATE A SINGLE PAGE PDF
    UIGraphicsBeginPDFPage();
    [legMain.layer renderInContext:pdfContext];
    UIGraphicsEndPDFContext();

    // CREATE PRINT CONTROLLER
    UIPrintInteractionController *pc = [UIPrintInteractionController sharedPrintController];
    void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
    ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
        if (!completed && error){
            NSLog(@"Print error: %@", error);
        }
    };

    // SETUP PRINT CONTROLLER
    [pc setShowsNumberOfCopies:YES];
    [pc setShowsPageRange:YES];
    [pc setShowsPaperSelectionForLoadedPapers:YES];
    pc.printingItem = pdfData;

    // DISPLAY CONTROLLER DIALOG
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        [pc presentFromRect:texName.frame inView:viewMain.superview
                   animated:YES completionHandler:completionHandler];
    } else {
        [pc presentAnimated:YES completionHandler:completionHandler];
    }

    // RESET BACKGROUND COLOUR AND FRAME SIZE
    [legMain setBackgroundColor:[UIColor colorWithRed:.95 green:.95 blue:.95 alpha:1.0]];
    [legMain setFrame:CGRectMake(legMain.frame.origin.x, legMain.frame.origin.y, dWidth, dHeight)];
}

legMain 是我正在调整并最终转换为 PDF 的视图。我已经设法移植了大部分代码,直到我到达需要渲染视图的第 26 行。我什至不知道从哪里开始获取我的视图实例。

【问题讨论】:

    标签: swift printing view swiftui


    【解决方案1】:

    按照How to access own window within SwiftUI view? 中的描述访问托管窗口,您可以从任何 SwiftUI 视图中获取主要的UIView

    let mainView = hostingWindow?.rootViewController.view
    

    但对于打印,我可能会使用如下专用视图(以避免影响 UI 视图)

    if let hostingController = hostingWindow?.rootController as UIHostingController {
        let printingView = UIHostingController(rootView: hostingController.rootView).view
    
        // ... do anything with printingView here, because it will have 
        //     a copy of SwiftUI rootView
    }
    

    更新:评论中的详细信息(在这种情况下不需要托管窗口)

    VStack {
       PrintableView(arg: value) // << need to be made undependable, so all 
                                 // parameters should be passed via arguments
    }
    

    然后在打印动作上可能是这样的

    Button("Print") {
       let printingView = UIHostingController(rootView: PrintableView(arg: value)).view
       // do anything printing related with `printingView` here
    }
    

    【讨论】:

    • 非常感谢您的回复,这真的难倒我。我不想打印整个视图,因为它有很多按钮、工具栏和状态文本。我试图打印的视图有一个 VStack 父级。那么如何引用这个 VStack 呢?有没有办法为其分配名称或ID?我假设您最后一个代码语句末尾的 .view 是我试图获得的视图?
    • 几乎可以正常工作。不知道如何发布新代码(对此很新)。我要开始新帖子吗?
    • 如果我使用一切都很好: let printingView = UIApplication.shared.windows[0].rootViewController?.view 但这会打印我的整个视图而不是所需的视图。您建议的代码只是打印一个空白页。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    相关资源
    最近更新 更多