iOS 10 Camera view showing API_Cancel_Title instead of Cancel

I've approached the same problem using BundleLocalization and I've traced UIImagePickerController keys, that it gets from a bundle.

Turns out, it uses 4 "tables" (in NSBundle nomenclature):

  • CameraUI (for camera)
  • PhotoLibraryServices (for PhotoLibrary)
  • PhotoLibrary (for PhotoLibrary)
  • PhotosUI (for PhotoLibrary)

In my case, all I had to do, to localize UIImagePickerController interface, it was create in the project a couple of .strings files and localize them.

Below content of mentioned files with keys I've seen (with standard english values), they are pretty self explaining

CameraUI.strings
"PHOTO" = "PHOTO";
"AEAF_LOCK_TEXT" = "AE/AF LOCK";
"API_CANCEL_TITLE" = "Cancel";
"HDR_AUTO" = "Auto";
"HDR_ON" = "On";
"HDR_OFF" = "Off";
"TIMER_OFF_TEXT" = "Off";
"USE_PHOTO" = "Use Photo";
PhotoLibraryServices.strings
"PHOTOS" = "Photos";
"CAMERA_ROLL" = "Camera roll";
"ALL_SCREENSHOTS" = "Screenshots";
PhotoLibrary.strings
"CANCEL" = "Cancel";
"RETAKE" = "Retake";
"STREAM_SHARED_BY_ME_SUBTITLE" = "From You";
"STREAM_SHARED_BY_SUBTITLE" = "From %@";
"ALBUM_IMAGE_COUNT_FORMAT" = "%@ Photos";
"ALBUM_VIDEO_COUNT_FORMAT" = "%@ Videos";
"1_ALBUM_PHOTO" = "1 Photo";
"1_ALBUM_VIDEO" = "1 Video";
"ALBUM_TWO_TYPES_LABEL_COMMAS" = "%@, %@";
PhotosUI.strings
"ALL_PHOTOS_IN_LIBRARY" = "Moments";
"PXUserCollectionsSectionTitle" = "My Albums";
"FULL_PHOTOS_GRID_ZOOM_LEVEL_TITLE" = "Moments";
"NO_PHOTOS_OR_VIDEOS" = "No Photos or Videos";
"EMPTY_ALBUM_LIST_MESSAGE_iPhone" = "You can take photos and videos using camera, or sync photos and videos onto your iPhone using iTunes";

On this Extension of Bundle You need to check for the CameraUI in tableName. Use that change the value for the key of "Api_Cancel_title" to "Cancel" Using your own Localized value where you used to declare a your own value

for example

English "API_CANCEL_TITLE" = "Cancel";

Hindi "API_CANCEL_TITLE" = "रद्द करना";

French "API_CANCEL_TITLE" = "Annuler";

// MARK: - Bundle Extension

extension Bundle {

    @objc func specialLocalizedStringForKey(_ key: String, value: String?, table tableName: String?) -> String {
        let currentLanguage = CSLanguage.currentAppleLanguage()
        var bundle = Bundle.main
        if let path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
            bundle = Bundle.init(path: path)!
        } else {
            let basePath = Bundle.main.path(forResource: "Base", ofType: "lproj")
            bundle = Bundle.init(path: basePath!)!
        }
        if let name = tableName, name == "CameraUI"{
         let values = NSLocalizedString(key, comment: name)

         return values
        }
        if let name = tableName, name == "PhotoLibrary"{
         let values = NSLocalizedString(key, comment: name)

         return values
        }
        if let name = tableName, name == "PhotoLibraryServices"{
         let values = NSLocalizedString(key, comment: name)

         return values
        }
        if let name = tableName, name == "PhotosUI"
        {
         let values = NSLocalizedString(key, comment: name)

         return values
        }
        return bundle.specialLocalizedStringForKey(key, value: value, table: tableName)
    }
}

I have an approach, I know it will be not a perfect solution however until get a perfect one, we can use this:

Use an custom camera view. Manage it with condition if device version is 10 or greater than 10 then execute custom camera view settings else use the default camera view.

By using custom view, the API_Cancel_Title button hides and rest of the functionality works well. Here is the link that I used for a reference: Removing the cancel button from Custom camera