lohanidamodar / pdf_viewer

A flutter plugin for handling PDF files. Works on both Android & iOS
https://pub.dev/packages/advance_pdf_viewer
BSD 3-Clause "New" or "Revised" License
61 stars 143 forks source link

Screen flickering - Viewer showing rendering failure on iOS #107

Open scherermathias opened 2 years ago

scherermathias commented 2 years ago

I've been having issues with displaying PDFs on iOS. When entering the PDF display screen, the first few pages are displayed correctly. When advancing the pages, they begin to show file rendering failures, displaying glitch's and the screen is blank, as shown in the gif below. I tried to reduce the size of the PDF to 1280x720 pixels (good quality - as small as possible), and this increased the amount of pages to be rendered without the error, but around page 13, the rendering error starts again.

The PDF was created by Keynote software (Apple - Mac OS), similar to PowerPoint.

Other tests performed:

1 - I tried to change it to a PDF I found on the internet, with 200 pages, and there was no problem when opening.

2 - I used the website https://www.ilovepdf.com/compress_pdf to compress the PDF, but it didn't solve the problem either.

3 - I found that it only occurs on iOS on physical cell phones. In debug/emulation, the bug does not occur. On the physical phone, the app doesn't close due to the bug, so I don't have any error logs.

I use Firebase to store the PDFs files in my Flutter app.

Gif showing the bug - from page 13. ezgif com-gif-maker

Here's the code:

import 'package:flutter/material.dart';
import 'package:advance_pdf_viewer/advance_pdf_viewer.dart';
import 'package:flutter/services.dart';
import 'package:twowin/constants/cores_constants.dart';

class ViewFilePage extends StatefulWidget {
  final String? file;
  const ViewFilePage({Key? key, this.file}) : super(key: key);

  @override
  _ViewFilePageState createState() => _ViewFilePageState();
}

class _ViewFilePageState extends State<ViewFilePage> {
  bool _isLoading = true;
  int page = 1;
  PDFDocument? document;
  var controller = PageController();

  @override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeLeft,
      DeviceOrientation.landscapeRight,
    ]);
    loadDocument();
  }

  loadDocument() async {
    document = await PDFDocument.fromURL(widget.file!.toString());

    setState(() => _isLoading = false);
  }

  @override
  void dispose() {
    controller.dispose();
    document = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitUp,
          DeviceOrientation.portraitDown,
        ]);
        return Navigator.canPop(context);
      },
      child: Scaffold(
        backgroundColor: kBackgroundColor,
        body: SizedBox(
          width: MediaQuery.of(context).size.width,
          child: _isLoading
              ? const Center(child: CircularProgressIndicator())
              : SafeArea(
                  child: Stack(
                    children: [
                      PDFViewer(
                        document: document!,
                        controller: controller,
                        enableSwipeNavigation: false,
                        showNavigation: false,
                        showIndicator: true,
                        showPicker: false,
                      ),
                      Positioned(
                        left: 20,
                        bottom: MediaQuery.of(context).size.height * 0.5,
                        child: IconButton(
                          icon: const Icon(Icons.arrow_back_ios, color: kPrimaryColor),
                          onPressed: () {
                            controller.previousPage(duration: const Duration(milliseconds: 400), curve: Curves.easeIn);
                          },
                        ),
                      ),
                      Positioned(
                        right: 20,
                        bottom: MediaQuery.of(context).size.height * 0.5,
                        child: IconButton(
                          icon: const Icon(Icons.arrow_forward_ios, color: kPrimaryColor),
                          onPressed: () {
                            controller.nextPage(duration: const Duration(milliseconds: 400), curve: Curves.easeIn);
                          },
                        ),
                      ),
                      Positioned(
                        left: 20,
                        child: IconButton(
                          onPressed: () {
                            SystemChrome.setPreferredOrientations([
                              DeviceOrientation.portraitUp,
                              DeviceOrientation.portraitDown,
                            ]);
                            Navigator.pop(context);
                          },
                          icon: const Icon(
                            Icons.close,
                            color: kPrimaryColor,
                            size: 30,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
        ),
      ),
    );
  }
}