Open-source project
ruslanskorb/RSKImageCropper avatar
ruslanskorb/RSKImageCropper

RSKImageCropper: A Contacts-Style Image Cropper for iOS

An image / photo crop view controller for iOS like in the Contacts app with support for landscape orientation.

2,446 stars463 forksObjective-CMIT

At a glance

What is it?
RSKImageCropper is an Objective-C view controller that reproduces the crop experience of the iOS Contacts app, including landscape orientation and custom mask shapes. It is a drop-in UI component, not a full image editing pipeline.
Who is it for?
Adopt RSKImageCropper if you need the Contacts-style crop interaction inside an Objective-C or Swift iOS app and are willing to implement a delegate and, for non-rectangular masks, a data source. Do not adopt it if you need a cross-platform cropper, a SwiftUI-native component, or an editing suite with filters and undo.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Objective-C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The Problem RSKImageCropper Solves

Cropping a photo sounds trivial until you have to build the interaction. The user needs to pan the image behind a fixed mask, pinch to zoom, rotate, and confirm a result that matches what the mask showed. Apple's Contacts app has had a polished version of this for years, and matching it by hand means writing gesture recognizers, a scroll view with custom content sizing, mask rendering, and a crop routine that maps the visible region back to original pixel coordinates.

RSKImageCropper packages that interaction as a UIViewController subclass. You hand it a UIImage, push it onto a navigation stack, and implement a delegate. The README describes it as "an image cropper for iOS like in the Contacts app with support for landscape orientation." The audience is iOS developers who want the standard system feel without reimplementing it, and who are comfortable with Objective-C headers imported into a Swift or Objective-C project.

The scope is deliberately narrow. There is no filter pipeline, no undo stack, no multi-image batch mode. The README's "Coming Soon" section contains only an invitation to raise an issue for new features, which tells you the maintainer treats the surface area as roughly complete.

How the View Controller, Delegate and Data Source Fit Together

The architecture is a standard UIKit delegation split. RSKImageCropViewController owns the view, the gestures and the crop math. RSKImageCropViewControllerDelegate reports outcomes back to your code. RSKImageCropViewControllerDataSource supplies geometry when you want a mask that is not the default.

The delegate has three methods. imageCropViewControllerDidCancelCrop: fires when the user backs out. imageCropViewController:didCropImage:usingCropRect:rotationAngle: fires with the finished UIImage plus the rectangle and rotation angle that produced it, which matters if you want to reproduce the crop later at higher resolution. imageCropViewController:willCropImage: fires before cropping begins, and the README ties it to the applyMaskToCroppedImage flag, suggesting you use it to show a progress indicator during a potentially slow operation.

The data source exposes three geometry hooks. imageCropViewControllerCustomMaskRect: returns the CGRect of the mask. imageCropViewControllerCustomMaskPath: returns a UIBezierPath, which is what lets you build a circular crop rather than a rectangle. imageCropViewControllerCustomMovementRect: returns the region in which the image may be panned, and the README's sample implementation widens that rect by the rotated bounding box of the mask so the image can still be positioned correctly after rotation. That last method is the one most likely to be implemented incorrectly, because a movement rect that is too tight produces visible dead zones at certain angles.

Installing RSKImageCropper with Swift Package Manager

The README states the minimum deployment target: iOS 12.0 or later. The only installation path it documents is Swift Package Manager. In Xcode, choose File > Swift Packages > Add Package Dependency and enter the repository URL:

bash
https://github.com/ruslanskorb/RSKImageCropper.git

The repository also ships a Package.swift at the top level, so a Package.swift-based dependency declaration works the same way. Once the package resolves, import the umbrella header in the file that will present the cropper:

objective-c
#import <RSKImageCropper/RSKImageCropper.h>

The README's basic usage example creates the controller from a UIImage and pushes it. Your view controller must declare conformance to the delegate protocol:

objective-c
@interface ViewController () <RSKImageCropViewControllerDelegate>

Then present it. This is the README's example, with the delegate assignment that makes the result come back to you:

objective-c
UIImage *image = [UIImage imageNamed:@"image"];
RSKImageCropViewController *imageCropViewController = [[RSKImageCropViewController alloc] initWithImage:image];
imageCropViewController.delegate = self;
[self.navigationController pushViewController:imageCropViewController animated:YES];

After that, implement the cancel and crop callbacks. If you forget to set the delegate, the controller still renders and still accepts gestures, but nothing you do will produce a cropped image, which is the most common first-run mistake.

Custom Mask Shapes and the Rotation Trap

The default mask is a rectangle, and the README's data source sample builds a 16:9 one by hand. The sample walks the mask width down one point at a time until the computed height lands on an integer, then adds the point back. That loop exists because a mask whose edges fall on fractional coordinates produces visible seams when the mask path is rendered. It is a small detail with an outsized effect on output quality, and it is the kind of thing you would not guess from the API alone.

The rotation angle is the harder part. When rotationAngle is zero, the README's imageCropViewControllerCustomMovementRect: returns the mask rect unchanged. When it is not zero, the sample computes the axis-aligned bounding box of the rotated mask using absolute cosine and sine terms, centers it on the mask, floors the origin, and passes the result through CGRectIntegral. If you supply a movement rect that ignores rotation, the user can pan the image into positions where the mask reveals empty space. The README does not document a validation step that catches this, so it is on you to test at intermediate angles, not just at zero and ninety degrees.

The mask path is a separate concern. The sample returns a four-point closed UIBezierPath for a rectangle, but the API accepts any path, which is how you would produce a circular avatar crop. Nothing in the README states how non-convex or self-intersecting paths behave.

Where RSKImageCropper Is the Wrong Choice

The component is iOS-only and UIKit-only. There is no documented SwiftUI wrapper, no macOS or tvOS target, and no Android or web equivalent. If your app is SwiftUI-first and you want to avoid UIViewControllerRepresentable bridging, this package adds a layer you will have to maintain.

The API is Objective-C. Swift consumers can use it, but the delegate methods arrive with Objective-C selector names, and the data source returns C structs and Core Graphics types. Projects that have moved to async/await presentation patterns will find the push-based navigation in the README's example dated, though nothing prevents you from presenting the controller modally instead.

There is also no documented handling of very large images. The willCropImage callback exists and the README associates it with applyMaskToCroppedImage, which implies cropping can take long enough to warrant a progress indicator, but the README gives no guidance on image size limits or memory behaviour. If your users crop 50-megapixel photos, you should measure that path yourself before shipping.

Finally, the README does not document rollback, undo, or re-cropping an already cropped result. Each presentation is a single pass.

How RSKImageCropper Differs from TOCropViewController

The closest alternative in the same space is TOCropViewController, another Objective-C iOS cropper. The difference is in the interaction model rather than the platform. TOCropViewController exposes a draggable, resizable crop box that the user manipulates directly, with aspect ratio presets and a rotation dial. RSKImageCropper inverts that: the mask is fixed and the image moves behind it, which is the Contacts app behaviour and produces a more constrained, more predictable result.

That inversion has consequences. With a fixed mask, the data source has to define the movement rect and the mask path, so custom shapes require more code than adjusting a crop box would. In exchange, the user cannot produce an off-center or oddly proportioned crop by accident, because the mask geometry is yours to define. If you want users to choose their own framing freely, the crop-box model fits better. If you want every output to conform to a shape you control, the fixed-mask model does.

Both projects are MIT-licensed and both are Objective-C, so the choice is about interaction design, not licensing or language.

Maintenance, Licence and Upgrade Cost

The repository is not archived, and the last push was on 2026-03-26, which is the same day release 6.0.0 was published. The release history shows 5.0.0 in November 2024, 5.0.1 in December 2024, and then 6.0.0 in March 2026, so releases arrive irregularly rather than on a schedule. Plan for a dependency that you may need to patch yourself rather than one that ships fixes quickly.

The 6.0.0 major version bump is the upgrade signal to watch. The README does not include a changelog or migration notes, so before moving from 5.x to 6.0.0 you should read the release entry on GitHub and check whether the delegate or data source signatures you depend on changed. Nothing in the README documents a deprecation path.

The licence is MIT, which permits commercial and closed-source use with the licence text retained. The README states that attribution by linking to the project page is appreciated, which is a request rather than a licence condition. This is not legal advice; read the LICENSE file in the repository for the binding terms.

One build detail worth knowing: the Makefile pins the simulator destination to platform='iOS Simulator',OS='26.2',name='iPhone 17 Pro' and defines build, test, clean and ci targets. If your CI machine does not have that exact simulator runtime installed, the Makefile targets will fail until you edit DEVICE_HOST. The Example directory holds RSKImageCropperExample.xcodeproj, which the README points to for a working demonstration.

Editorial conclusion

Adopt RSKImageCropper if you need the Contacts-style crop interaction inside an Objective-C or Swift iOS app and are willing to implement a delegate and, for non-rectangular masks, a data source. Do not adopt it if you need a cross-platform cropper, a SwiftUI-native component, or an editing suite with filters and undo. Before wiring it in, verify that your deployment target is iOS 12.0 or later, that your mask geometry is correct at every rotation angle, and that your delegate handles the willCropImage callback when applyMaskToCroppedImage is set to YES.

Frequently asked questions

How do I install RSKImageCropper in an Xcode project?

The README documents Swift Package Manager only: select File > Swift Packages > Add Package Dependency and enter https://github.com/ruslanskorb/RSKImageCropper.git. The package requires iOS 12.0 or later.

Does RSKImageCropper support landscape orientation?

Yes. The README describes it as an image cropper for iOS like in the Contacts app with support for landscape orientation, and the data source sample branches on isPortraitInterfaceOrientation to size the mask.

Can I use a circular mask instead of a rectangle with RSKImageCropper?

The data source method imageCropViewControllerCustomMaskPath: returns a UIBezierPath, and the README's sample returns a four-point rectangle. Because the API accepts any path, a circle is possible, but the README does not document how non-rectangular paths behave.

Is RSKImageCropper still maintained?

The repository is not archived and the last push was on 2026-03-26, the same day version 6.0.0 was released. Release dates are irregular, with 5.0.0 and 5.0.1 in late 2024 and 6.0.0 in March 2026.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. ruslanskorb/RSKImageCropper on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ruslanskorb-rskimagecropper.svg)](https://hysenlabs.com/projects/ruslanskorb-rskimagecropper)