Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

ios - Perform "use photo" button on custom image picker overlay

I am creating fully custom overlay for image picker controller. First stage is easy: I am get first view with record/take a shot button, which call takePicture() method.

Next stage is change UI to "Retake" or "Use photo" which is also with my own design. "Retake" probably can be imitated by calling presentViewController again. How should I imitate "Use photo" button?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can easily inherit UIImagePickerController

Objective-C

@interface CameraViewController : UIImagePickerController

@property (readwrite, nonatomic) NSInteger state; // 0 - auto 1 - on 2 - off

@end

@implementation CameraViewController

- (instancetype)init {
    self = [super init];
    if (self) {
        if (!TARGET_IPHONE_SIMULATOR) {
            self.sourceType = UIImagePickerControllerSourceTypeCamera;
            self.showsCameraControls = NO;
            self.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
        } else {
            self.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        }
        self.modalPresentationStyle = UIModalPresentationFullScreen;
        self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        self.allowsEditing = NO;
        self.mediaTypes = @[(NSString *)kUTTypeImage];
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(orientationChanged)
                                                     name:UIDeviceOrientationDidChangeNotification
                                                   object:nil];

    }
    return self;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end

Then override viewDidLoad and customize UI to your needs by creating UIView object and set it to self.cameraOverlayView. In my example it is custom flash button.

- (void)viewDidLoad {
    [super viewDidLoad];

    UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];
    view.backgroundColor = [UIColor clearColor];
    UIButton *changeFlashButton = [UIButton buttonWithType:UIButtonTypeCustom];
    changeFlashButton.frame = CGRectMake(70, 27, 40, 40);
    [changeFlashButton setImage:[UIImage imageNamed:@"flash_auto"] forState:UIControlStateNormal];
    self.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
    changeFlashButton.showsTouchWhenHighlighted = YES;
    [changeFlashButton addTarget:self action:@selector(changeFlashValue:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:changeFlashButton];
    if (!TARGET_IPHONE_SIMULATOR) {
        self.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
        changeFlashButton.alpha = [[self class] isFlashAvailableForCameraDevice:self.cameraDevice];
        self.cameraOverlayView = view;
    }
}

- (void)changeFlashValue:(UIButton*)aSwitch {
    if (self.state == 0) { //auto - on
        self.state = 1;
        [self.flashSwitch setImage:[UIImage imageNamed:@"flash_on"] forState:UIControlStateNormal];
        self.cameraFlashMode = UIImagePickerControllerCameraFlashModeOn;
        return;
    }
    if (self.state == 1) { //on - off
        self.state = 2;
        [self.flashSwitch setImage:[UIImage imageNamed:@"flash_off"] forState:UIControlStateNormal];
        self.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
        return;
    }
    if (self.state == 2) { //off - auto
        self.state = 0;
        [self.flashSwitch setImage:[UIImage imageNamed:@"flash_auto"] forState:UIControlStateNormal];
        self.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
        return;
    }
}

Your controls of camera could be like this from left-to-right: flash, take picture, front/rear camera, photo-gallery

Please pay attentions that for not showing to user "Retake" and "Use photo" buttons you need to set allowsEditing to false

And actually the same for Swift 2.2+

class CameraViewController: UIImagePickerController {

    var state: Int?

    init() {
        super.init(navigationBarClass: nil, toolbarClass: nil)
        #if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS)) // any simulator
            self.sourceType = .PhotoLibrary
        #else
            self.sourceType = .Camera
            self.showsCameraControls = false
            self.cameraCaptureMode = .Photo
        #endif

        self.modalPresentationStyle = .FullScreen
        self.modalTransitionStyle = .CrossDissolve
        self.allowsEditing = false
        self.mediaTypes = [UIImagePickerControllerMediaType]
        UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(orientationChanged), name: UIDeviceOrientationDidChangeNotification, object: nil)
    }

    // strange compiler requirements
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func orientationChanged() {
        // update to the new orientation
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let view: UIView = UIView(frame: self.view.bounds)
        view.backgroundColor = UIColor.clearColor()
        var changeFlashButton: UIButton = UIButton(type: .Custom)
        changeFlashButton.frame = CGRectMake(70, 27, 40, 40)
        changeFlashButton.setImage(UIImage(named: "flash_auto"), forState: .Normal)
        self.cameraFlashMode = .Auto
        changeFlashButton.showsTouchWhenHighlighted = true
        changeFlashButton.addTarget(self, action: #selector(changeFlashValue(_:)), forControlEvents: .TouchUpInside)
        view.addSubview(changeFlashButton)
        #if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS)) // any simulator
        #else
            self.cameraFlashMode = .Auto
            changeFlashButton.alpha = UIImagePickerController.isFlashAvailableForCameraDevice(self.cameraDevice) ? 1 : 0
        #endif
    }

    func changeFlashValue(aSwitch: UIButton) {
        if self.state == 0 {
            // auto - on
            self.state = 1
            self.flashSwitch.setImage(UIImage.imageNamed("flash_on"), forState: .Normal)
            self.cameraFlashMode = .On
            return
        }
        if self.state == 1 {
            // on - off
            self.state = 2
            self.flashSwitch.setImage(UIImage.imageNamed("flash_off"), forState: .Normal)
            self.cameraFlashMode = .Off
            return
        }
        if self.state == 2 {
            // off - auto
            self.state = 0
            self.flashSwitch.setImage(UIImage.imageNamed("flash_auto"), forState: .Normal)
            self.cameraFlashMode = .Auto
            return
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...