Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ public class FlutterPDFView implements PlatformView, MethodCallHandler {
pdfView.setBackgroundColor(color);
}

Object maxZoom = params.get("maxZoom");
if (maxZoom != null) {
float max = ((Number) maxZoom).floatValue();
// NOTE: Android's PDFView zoom scaling is about half of iOS PDFKit.
// Multiply by 2 to normalize so that a Dart value like maxZoom = 3.0
// results in ~300% zoom on both iOS and Android.
pdfView.setMaxZoom(max * 2);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Android Zoom Bug Causes Inconsistency

Android's maxZoom parameter is multiplied by 2, leading to inconsistent maximum zoom levels compared to iOS. The implementation also casts maxZoom to Number without a type check, which could cause a ClassCastException at runtime.

Fix in Cursor Fix in Web

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note on Android maxZoom implementation

On Android, the underlying PDFView (from android-pdf-viewer) uses a different internal scaling model compared to iOS PDFKit.
If we pass the same numeric value for maxZoom directly, the perceived zoom level on Android will look significantly smaller than on iOS.

To make the behavior consistent across platforms, the Android implementation multiplies maxZoom by 2.
This way, when developers pass the same maxZoom value in Dart, the visual zoom level on Android and iOS appears similar.


if (config != null) {
config
.enableSwipe(getBoolean(params, "enableSwipe"))
Expand Down
6 changes: 5 additions & 1 deletion ios/flutter_pdfview/Sources/flutter_pdfview/FlutterPDFView.m
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ - (instancetype)initWithFrame:(CGRect)frame
}
_pdfView.document = document;

_pdfView.maxScaleFactor = [args[@"maxZoom"] doubleValue];
NSNumber *maxZoom = args[@"maxZoom"];
if (maxZoom != nil && [maxZoom isKindOfClass:[NSNumber class]]) {
_pdfView.maxScaleFactor = [maxZoom doubleValue];
}

Comment on lines +168 to +172
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

iOS: maxZoom should be relative to fit and not get overwritten on layout; clamp double‑tap to max.

  • Current code sets maxScaleFactor to the raw number, then layout sets it back to 4.0, breaking the new API.
  • Implement “relative to fit” semantics consistently and clamp double‑tap to respect max.

Apply this diff in the changed block to compute max relative to fit and remember the multiple:

-        NSNumber *maxZoom = args[@"maxZoom"];
-        if (maxZoom != nil && [maxZoom isKindOfClass:[NSNumber class]]) {
-            _pdfView.maxScaleFactor = [maxZoom doubleValue];
-        }
+        NSNumber *maxZoom = args[@"maxZoom"];
+        if ([maxZoom isKindOfClass:[NSNumber class]]) {
+            _maxZoomMultiple = MAX(1.0, [maxZoom doubleValue]); // store the multiple
+            _pdfView.maxScaleFactor = _pdfView.scaleFactorForSizeToFit * _maxZoomMultiple;
+        }

Add an ivar and a sensible default (outside the changed lines):

// Near other ivars
double _maxZoomMultiple;

// In -initWithFrame:... before using it
_maxZoomMultiple = 3.0;

Update layout to recompute absolute max from the current fit scale and clamp the current zoom (outside the changed lines):

// In -layoutSubviews (replace the hard-coded 4.0)
_pdfView.maxScaleFactor = _pdfView.scaleFactorForSizeToFit * (_maxZoomMultiple > 1.0 ? _maxZoomMultiple : 3.0);
if (_pdfView.scaleFactor > _pdfView.maxScaleFactor) {
    _pdfView.scaleFactor = _pdfView.maxScaleFactor;
}

Respect max on double‑tap zoom (outside the changed lines):

// Where scaleFactor is set to scaleFactorForSizeToFit * 2
CGFloat target = MIN(self->_pdfView.scaleFactorForSizeToFit * 2.0, self->_pdfView.maxScaleFactor);
self->_pdfView.scaleFactor = target;

Also applies to: 257-264, 341-348

🤖 Prompt for AI Agents
In ios/flutter_pdfview/Sources/flutter_pdfview/FlutterPDFView.m around lines
168-172, the code currently assigns maxScaleFactor directly from the raw maxZoom
number which gets overwritten on layout; change it to store a relative multiple
(add a double _maxZoomMultiple ivar near other ivars and initialize it to 3.0 in
initWithFrame:), when handling args compute and save the multiple (e.g.
_maxZoomMultiple = maxZoomValue; do not set absolute max here), update
layoutSubviews to recompute the absolute max as scaleFactorForSizeToFit *
(_maxZoomMultiple > 1.0 ? _maxZoomMultiple : 3.0) and clamp current scaleFactor
to that max, and update the double-tap zoom logic to cap the target zoom with
the recomputed maxScaleFactor so double-tap respects the configured max; apply
the same pattern to the other mentioned blocks (lines 257-264, 341-348).

_pdfView.minScaleFactor = _pdfView.scaleFactorForSizeToFit;

NSString* password = args[@"password"];
Expand Down
9 changes: 9 additions & 0 deletions lib/flutter_pdfview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class PDFView extends StatefulWidget {
this.fitPolicy = FitPolicy.WIDTH,
this.preventLinkNavigation = false,
this.backgroundColor,
this.maxZoom = 3.0,
}) : assert(filePath != null || pdfData != null),
assert(maxZoom > 1.0, 'maxZoom must be greater than 1.0'),
super(key: key);

@override
Expand Down Expand Up @@ -119,6 +121,9 @@ class PDFView extends StatefulWidget {

/// Use to change the background color. ex : "#FF0000" => red
final Color? backgroundColor;

/// Use to change the maximal zoom. Must be greater than 1.0, default 3.0.
final double maxZoom;
}

class _PDFViewState extends State<PDFView> {
Expand Down Expand Up @@ -237,6 +242,7 @@ class _PDFViewSettings {
this.fitPolicy,
this.preventLinkNavigation,
this.backgroundColor,
this.maxZoom,
});

static _PDFViewSettings fromWidget(PDFView widget) {
Expand All @@ -252,6 +258,7 @@ class _PDFViewSettings {
fitPolicy: widget.fitPolicy,
preventLinkNavigation: widget.preventLinkNavigation,
backgroundColor: widget.backgroundColor,
maxZoom: widget.maxZoom,
);
}

Expand All @@ -267,6 +274,7 @@ class _PDFViewSettings {
final bool? preventLinkNavigation;

final Color? backgroundColor;
final double? maxZoom;

Map<String, dynamic> toMap() {
return <String, dynamic>{
Expand All @@ -281,6 +289,7 @@ class _PDFViewSettings {
'fitPolicy': fitPolicy.toString(),
'preventLinkNavigation': preventLinkNavigation,
'backgroundColor': backgroundColor?.value,
'maxZoom': maxZoom,
};
}

Expand Down