The Problem
When a user toggles radio buttons or checkboxes in a PDF using Preview, the widgets disappear following subsequent interactions after the file is saved and reopened. This renders the form fields unusable.
Steps to Reproduce the Problem
- Open a PDF with radio buttons or checkboxes in Preview.
- Toggle a radio button or checkbox.
- Save and close the file.
- Re-open the PDF in Preview.
- Toggle the same button again. The button (and any others with the same field name) will disappear.
Expected Results
Toggling a radio button or checkbox should update the field value without causing the button (or related buttons) to disappear. This behavior is consistent with previous versions of PDFKit.
What is Happening
In Preview, interacting with radio buttons and checkboxes correctly updates their appearance as expected. Saving the PDF, however, causes the appearance dictionary to reference a new N entry that is a single appearance stream unassociated with any state. The annotation's AS entry is not updated. The original N entry remains but is no longer referenced. Subsequent interactions fail to update the visual presentation because the appearance stream is missing.
Impact on User Experience
- Radio buttons and checkboxes may disappear and become unusable when toggled.
- PDF documents become irreparably altered after a button is toggled and the file is saved.
- PDF file size significantly increases when the file is saved.
- Users may believe they have successfully completed a form, only for the data to become inaccessible or invisible to recipients.
- Forms may need to be completely restarted or recreated from scratch if the original becomes unusable.
- The corrupted PDF structure might cause the file to render incorrectly or crash in third-party PDF viewers.
Affected Apps/OSs
Tested with Preview 11.0 (1147), as well as other apps that use PDFKit, on macOS Golden Gate 27.0 (26A428).
This problem also affects PDFKit on iOS 27.0 and iPadOS 27.0.
Feedback/bug report: FB24866826
Related Sample Output
Original PDF File
Checkbox widget annotation (6 0 obj), its appearance dictionary (17 0 obj), and normal appearance dictionary (18 0 obj). Button is not checked.
6 0 obj
<<
/Border [ 0 0 0 ]
/Rect [ 90 390 110 410 ]
/T (button1)
/F 4
/Subtype /Widget
/DA (/.AppleSystemUIFont 13 Tf 0 g)
/MK 16 0 R
/C [ 0 ]
/AP 17 0 R
/V /Off
/M (D:20260919225320Z00'00')
/AS /Off
/FT /Btn
/Type /Annot
/Ff 0
>>
endobj
17 0 obj
<< /N 18 0 R >>
endobj
18 0 obj
<< /Yes 20 0 R /Off 22 0 R >>
endobj
PDF File after Save
Checkbox widget annotation object (6 0 obj), its new appearance dictionary object (8 0 obj), a new normal appearance stream object (20 0 obj), and the original appearance stream dictionary (now 21 0 obj). File saved after user checked button.
6 0 obj
<<
/Ff 0
/Type /Annot
/AS /Off
/AP 8 0 R
/MK 9 0 R
/C [ 0 ]
/FT /Btn
/M (D:20260919225320Z00'00')
/DA (/.AppleSystemUIFont 13 Tf 0 g)
/Subtype /Widget
/F 4
/Border [ 0 0 0 ]
/Rect [ 90 390 110 410 ]
/T (button1)
/V (Yes)
>>
endobj
8 0 obj
<< /N 20 0 R >>
endobj
20 0 obj
<<
/Filter /FlateDecode
/Resources <<
/ColorSpace <<
/CS1 [ /ICCBased 29 0 R ]
/CS2 [ /ICCBased 30 0 R ]
>>
>>
/BBox [ 0 0 20 20 ]
/Type /XObject
/Subtype /Form
/Length 123
>>
stream
xUéA¬0Ô}≈|†≈nà¢úÛÇ*—SA
=}Ïr(»ñµ≤w◊€YËà’|ÙÎŒç'óRï∂#SäÏÌü∞¢S‰Ì§ôRÌX}–É•åYÉçˆ BŒH"*â´8™ˆZø6z⁄ÿ ”ú6É€à©"∫t˘‹;'¬
endstream
endobj
21 0 obj
<< /Off 22 0 R /Yes 23 0 R >>
endobj
Note: No object references 21 0 obj in the PDF.