SwiftUI распечатать вид - PullRequest
       75

SwiftUI распечатать вид

0 голосов
/ 04 марта 2020

У меня есть старое приложение iOS, которое использует UIKit и Objective C, которые я сейчас портирую на SwiftUI и Swift. Все шло отлично, и я люблю Swift и SwiftUI. Приложение в значительной степени готово, но оно опирается на то, что пользователь может распечатать и / или сохранить основной вид в формате PDF. Я просто не могу понять, как получить доступ к представлению в swiftui, чтобы преобразовать его в PDF. Вот моя существующая / рабочая цель - 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, где мне нужно визуализировать представление. Я даже не знаю, где начать получать экземпляр моего взгляда.

1 Ответ

0 голосов
/ 04 марта 2020

Имея доступ к окну хостинга, как описано в Как получить доступ к собственному окну в представлении SwiftUI? вы можете получить основной UIView из любого представления SwiftUI как

let mainView = hostingWindow?.rootViewController.view

, но для печати я бы, вероятно, использовал выделенный вид, как показано ниже (чтобы не влиять на вид интерфейса)

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
}

тогда в действии Print это может выглядеть как

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