In the previous 2 posts, I talked about the secrets of view hierarchy and how to retrieve image from the UIImagePickerController. By understanding the internals of a UIImagePickerController, we are able to change some of the undocumented features. Steve Nygard has published an excellent class dumping utility. Eric Sadun‘s script make use of Steve’s class-dump to create a folder and fill it with header files from the iPhone’s private and public framework. I am going to share some of the information I have inferred from these header files.
The UIImagePickerController (PLCameraViewController) is a delegate of CameraView (/0/0/0). In the viewfinder mode, CameraView sends cameraViewCancelled: to its delegate when the Cancel button is pushed. If the Camera button is pushed, the following messages is sent in sequence: cameraViewShouldShowIris:, cameraViewShouldShowProgressWhileCapturing:, cameraViewShouldShowPreviewAfterSelection:. After “Use Photo” is pushed, cameraView:photoSaved: will be sent to its delegate. By using CameraView’s setDelegate:, you can assign a new delegate. I have successfully change the CameraView’s to my UIImagePickerController’s subclass. If you change the CameraView’s delegate, I will advice you to implement all 4 methods, and remember to forward these messages to the parent in these implementations.
In similar manner, cropOverlayWasCancelled:, cropOverlayWasOKed:, and cropOverlay:didFinishSaving: are sent to CameraView from PLCropLayer (/0/0/0/3). I guess you can customize the UI by playing with the (void)setShowsCropOverlay:(BOOL)fp8 and (void)setChangesStatusBar:(BOOL)fp8 methods in CameraView.
(void)setCropTitle:(id)fp8 subtitle:(id)fp12 buttonTitle:(id)fp16 looks interesting, but I can’t use it due to the limitation of NSObject’s performSelector. The titles (in view and buttons) can still be changed using the follow code:
There are more to be discovered, I leave the rest of the exploration to you.
Part 1 | Part 2
WARNING: Readers are adviced not to use the techniques presented in this 3 parts series. It is against the terms stated in the iPhone Developer Program. When undocumented features are used, the application may not work when a newer iPhone OS is released. DO IT AT YOUR OWN RISK.
Posted in
Tao Of Programming at June 15th, 2009.
No Comments.
Acknowledgement: I did not discover everything on my own. I am using some information from lajos, The Air Source, and Erica Sadun.
The UIImagePickerController allows an application to use camera to take picture. Customization is very limited. Taking picture through a camera is a 2 steps process:
- When UIImagePickerController (sourceType=UIImagePickerControllerSourceTypeCamera) is launched, user will be presented with a view finder. There is a “Take Picture” title on the top, Cancel button at bottom-left, and a Camera button at the bottom-right of the screen.
- When Camera button is pressed, user will be taken to another (confirmation) screen. It has “Retake” and “Use Photo” buttons.
There are only 3 configurable properties, but developers want more customizations. Initially my intention was to skip the confirmation screen, grab the picture after the Camera button is pressed. I start off by exploring the view hierarchy of UIImagePickerContorller.
This little piece of function will traverse the view hierarchy in a preorder manner:
Create a subclass of UIImagePickerController and add this function to its implementation. Invoke this function in viewDidAppear::
I will encourage you to inspect the view in the viewDidLoad and viewWillAppear: methods to compare the differences.
View hierarchy in iPhone simulator:
- UILayoutContiainerView (root)
- UITransitionView (/0)
- UIView (/0/0)
- PLCameraView (/0/0/0)
- UIImageView (/0/0/0/0)
- UIView (/0/0/0/1)
- PLCropOverlay (/0/0/0/2)
- UIImageView (/0/0/0/2/0)
- PLCropLCDLayer (/0/0/0/2/1)
- TPBottomDualButtonBar (/0/0/0/2/2)
- TPPushButton (/0/0/0/2/2/0)
- TPCameraPushButton (/0/0/0/2/2/1)
- UIImageView (/0/0/0/2/2/1/0)
- UINavigationBar(/0)
- UINavigationItemView (/1/0)
View hierarchy in iPhone (viewfinder mode):
- UILayoutContiainerView (root)
- UITransitionView (/0)
- UIView (/0/0)
- PLCameraView (/0/0/0)
- UIView (/0/0/0/0) The shutter image layer.
- UIImageView (/0/0/0/1)
- UIView (/0/0/0/2)
- PLCropOverlay (/0/0/0/3)
- UIImageView (/0/0/0/3/0)
- PLCropLCDLayer (/0/0/0/3/1)
- TPBottomDualButtonBar (/0/0/0/3/2)
- TPPushButton (/0/0/0/3/2/0)
- TPCameraPushButton (/0/0/0/3/2/1)
- UIImageView (/0/0/0/3/2/1/0)
- UINavigationBar(/0)
- UINavigationItemView (/1/0)
View hierarchy in iPhone (after picture is taken):
- UILayoutContiainerView (root)
- UITransitionView (/0)
- UIView (/0/0)
- PLCameraView (/0/0/0)
- UIView (/0/0/0/0)
- UIImageView (/0/0/0/1)
- PLImageTile (/0/0/0/2)
- PLRotationView (/0/0/0/2/0)
- PLImageScroller (/0/0/0/2/0/0)
- PLImageView (/0/0/0/2/0/0/0)
- PLCropOverlay (/0/0/0/3)
- UIImageView (/0/0/0/3/0)
- PLCropLCDLayer (/0/0/0/3/1)
- TPBottomDualButtonBar (/0/0/0/3/2)
- TPPushButton (/0/0/0/3/2/0)
- TPCameraPushButton (/0/0/0/3/2/1)
- UIImageView (/0/0/0/3/2/1/0)
- UINavigationBar(/0)
- UINavigationItemView (/1/0)
Part 2 | Part 3
WARNING: Readers are adviced not to use the techniques presented in this 3 parts series. It is against the terms stated in the iPhone Developer Program. When undocumented features are used, the application may not work when a newer iPhone OS is released.DO IT AT YOUR OWN RISK.
Posted in
Tao Of Programming at June 10th, 2009.
2 Comments.