Skip to content

Improved stability of the 90 degree rotation feature - #648

Merged
TimOliver merged 5 commits into
mainfrom
split/2-rotation-geometry
Jul 28, 2026
Merged

Improved stability of the 90 degree rotation feature#648
TimOliver merged 5 commits into
mainfrom
split/2-rotation-geometry

Conversation

@TimOliver

Copy link
Copy Markdown
Owner

No description provided.

…input guards

- Setting an angle of ±360 or beyond infinite-looped on the main thread,
  since the rotation logic wraps its angle to 0 at a full revolution; the
  setter now normalizes into that range and compares signed values, which
  also makes direction changes like 90 -> -90 work
- gridOverlayHidden passed the old ivar instead of its parameter, making
  plain assignment a no-op; the animated variant also honors its flag now
- A zero-sized image no longer produces NaN layout geometry, and aspect
  ratios with a single zero component revert to the image ratio

Adds the first real unit tests around TOCropView's public setters.
The focus-point mapping after a 90-degree rotation assumed the zoom
always changed by the geometric fitting scale, but the branch that
restores a previously edited crop applies a different zoom delta,
throwing the offset into the wrong coordinate space. The offset is now
mapped by the zoom ratio that was actually applied.

Also corrects the post-rotation and device-rotation maximum-offset
clamps (both disagreed with the proven form used by the recenter
animation) and keeps maximumZoomScale in step wherever
minimumZoomScale is rescaled, so extreme-aspect images can always
fill the crop box.
imageCropFrame floored its origin and ceiled its size independently,
so an edge-flush crop at a fractional zoom could overhang the image by
a point, which rendered as a black hairline on opaque exports.
- The scroll view's zoom ceiling is now derived in one place from a new
  baseMaximumZoomScale that is captured and restored alongside the rest of the
  rotation state, replacing the ad-hoc MAX() guards that let the configured
  maximumZoomScale drift after repeated rotations or crop box edits
- setAngle: bails out instead of spinning forever when a rotation makes no
  progress, and the two identical loops are collapsed into one
- imageCropFrame clamps its origin inside the image so the size can't go
  negative during rubber-band overscroll
- rotateImageNinetyDegreesAnimated:clockwise:completion: reports back on the
  un-animated path and when the call is dropped, rather than dropping the handler
- -_willRotateToInterfaceOrientation: no longer passes an inverted vertical
  layout flag when sizing the crop view
@TimOliver
TimOliver merged commit 0056cf8 into main Jul 28, 2026
1 check passed
@TimOliver
TimOliver deleted the split/2-rotation-geometry branch July 28, 2026 14:58
pull Bot pushed a commit to jasonkneen/TOCropViewController that referenced this pull request Jul 28, 2026
3.1.2 was already tagged and pushed to CocoaPods trunk on 2026-04-07, so this
work needed a new version number. It's a minor rather than a patch bump because
the release changes public API: TOCropView.gridOverlayView, and TOCropToolbar's
doneTextButton and cancelTextButton, are now annotated nullable, which is
source-breaking for Swift callers that access them directly.

Bumps both podspecs and all four MARKETING_VERSIONs, dates the accumulated
release notes, and links each entry to the pull request it came from (TimOliver#648
through TimOliver#651; the build fix went to main directly and has no PR).

Also moves the TimOliver#636 fix up out of the 3.1.1 section, where it had been filed
after that release went out, and splits it into the two distinct fixes it
actually made. main's 3.1.2 heading gains the underline every other heading in
the file has.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant