Removing cancel button in UIImagePickerController? - iphone

I am developing an app for ios 5.
I need to remove the cancel button on UIImagePickerController i searched for this problem on the forum but didnt get exact answer can someone please help me with this?

That is because it is not possible to remove that cancel button. That is an inbuilt function and you can not make changes in the same.

Swift Version, compatible 4+
To remove the navigation bar :
imagePicker.view.subviews
.filter { $0.isKind(of: UINavigationBar) }
.forEach { $0.isHidden = true }
for removing the buttons only :
imagePicker.view.subviews
.filter { $0.isKind(of: UIButton) }
.forEach { $0.isHidden = true }
VoilĂ 

I will give the best method to achieve this:
First create a subclass of the UiImagePickerController
in the subclass respond to the UINavigationBarDelegate method
- (BOOL)navigationBar:(UINavigationBar *)navigationBar
shouldPushItem:(UINavigationItem *)item
you dont have to do anything like setting the delegate or adding a protocol, just override the method inside your custom UIImagePcikerController.
in this method return NO for the cancel item (which is the first one)

I did this with ELCImagePickerController

There isn't a way to remove only the cancel button. UIImagePickerController exposes a property called showCameraControls, which will hide the bottom bar with the cancel button and the camera button, as well as the controls for flash, HDR, and flip camera, giving you just the camera preview.
If you want to provide an experience without a cancel button, you'll have to create a camera overlay view of what you want.
Assuming you have code invoking UIImagePickerController, you can turn off camera controls like this:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setShowsCameraControls:NO];
Assuming you'll overlay it with your own view without the cancel button, you'll add this (assuming you have a UIView called cameraOverlay:
[imagePicker setCameraOverlayView:cameraOverlay];

This will hide Navigationbar itself along with the Cancel and Title
let videoPicker = UIImagePickerController()
for view in videoPicker.view.subviews {
if let navBar = view as? UINavigationBar {
navBar.isHidden = true
}
}
If you want to remove the cancel button alone, dig deep into navBar

When you present the UIImagePickerView try puting the below code
for (UIView *subview in view.subviews) {
NSLog(#"subviews=%#",subview);
NSString *className = [NSString stringWithFormat:#"%#", [subview class]];
}
By the above code you can get the navigation controller used for displaying the cancel button.. Once you get the navigationController Set its leftside button to nil..
I have not used it but hope it can be of help to you

Related

Redefine Retake function in UIIMagePickerController use custome overlayview

I use custome overlay view in UIIMagepickercontroller and set
imagePicker.showsCameraControls = NO;
So after take picture, it's not have Retake button and I create toolbarbuttonitem "retake"but I don't know how to recall UIImagepickercontroller when pressed retake button.
I had create custom overlayview and then add toolbarbuttonitem in it. I use follow codes :
- (void)retakePressed:(id)sender {
NSLog(#"retakePressed...");
// TODO: take picture!
[self dismissModalViewControllerAnimated:YES];
}
When i using bellow codes, it call Viewcontroller not uiimagepicker
Can you help me? Thanks in advance

UIToolbar items disappear - Weird bug in ios6

This is the current setup.
I have the navigationController's toolbar with 5 buttons, and tapping on them hides the toolbar for 2 seconds, and then shows the toolbar again (except the 5th button - which brings up an actionsheet with buttons (ACTION & CANCEL)).
On tapping on the 1-4 buttons, I do a self.navigationController.toolbarHidden = YES; and after exactly 2 seconds, I set the self.navigationController.toolbarHidden = NO; and this brings back the toolbar, and everything's fine.
On tapping the 5th button, which brings up action sheet.
If i tap on CANCEL actionsheet => actionSheet dismissed => Toolbar is fine.
If I tap on ACTION button I do a self.navigationController.toolbarHidden = YES; and after 2 seconds... self.navigationController.toolbarHidden = NO;
but now... The toolbar buttons are GONE.
Further investigating...
I can see the the toolbarButtons seem to have their alpha values set to 0.
I have no idea why the toolbar items' alpha are set to value = 0 after actionsheet operation.
Can anyone tell me the root cause for this?
Have you tried setting the toolbar items array to nil? I had this same problem and it turned out that putting a check around when you set the toolbar's items seemed to work:
if ([self.navigationController.toolbar.items count] > 0) {
[self.navigationController.toolbar setItems:nil];
}
[self.navigationController.toolbar setItems:toolbarItems]; //toolbarItems is your array of UIBarButtonItems.
I managed to fix the issue in a different way. I hide the toolbar when the action sheet comes up, and after the buttonAction(), I essentially show the toolbar again.
This solves the problem where the toolbarItems disappear.
But the reason as to why the toolbarItems disappear and set alpha=0 is still a mystery for me. If anyone finds out the reason, please let me know :)
I had the same issue and reproduced it in one of the samples. It appears to be a bug in iOS6 when setting up toolbar items manually in loadView / viewDidLoad, then later calling an ActionSheet.
The code below is a workaround it -
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSArray* items = self.toolbarItems;
[self setToolbarItems:nil];
[self setToolbarItems:items animated:NO];
}
I solve it by moving action code to separate method and then calling it through sending message performSelector:withObject:afterDelay: with 0.25f second delay
Example:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
[self performSelector:#selector(logout) withObject:nil afterDelay:0.25f];
}
}
I don't know if it's the case, I found out that the disappeared items were actually in the toolbar, but placed over the bottom of the view. Maybe resetting them on certain circumstances may cause autolayout issues.
I fixed it by calling the setNeedLayout method on the viewcontroller's view (not the navigationControllers')
self.toolbarItems = toolButtons;
[self.view setNeedsLayout];

Replace or extend UIBarButtonItem selector

I'm trying to make a custom UIToolbar which handles rotation and custom arrangement. When it's in portrait mode some of the barbuttonitems will not be visible, so I add a "more" button from which pops up a little view with these items. My problem is that when my current orientation is portrait and when I select a visible barbuttonitem ( which is not in popup ) I want to close the popup if it's open. I want the smae behavior for the uibarbuttons in the popupview to close the popup after tap.
So I'm trying to replace somehow the UIBarButtonItem's selector with my own, in which I call the already defined actions, like this :
-(SEL)extendOriginal:(UIBarButtonItem *) uibb
{
if (popup) popup.hidden = YES;
[uibb.target performSelector:uibb.action];
// return ?? do what ??
}
But how do I replace the original selector to call this custom method with my custom UIToolbar as its target ? Or how could I "extend" the original selector with this call ? Sorry if question is lame :)
Edit: In other words, I want 2 actions with 2 separate targets to be executed when UIBarButtonItem is tapped.
Thanks!
This -(SEL)extendOriginal:(UIBarButtonItem *) uibb doesn't make any sense.
I assume your are setting the target and the action of the bar button item somewhere. There you can set any method with one argument id or UIBarButtonItem* as the selector.
Therefore try to change your code to
- (void)myMethod:(UIBarButtonItem *) uibb
{
if (popup) popup.hidden = YES;
// do cool stuff here
}
and set the target as
[[UIBarButtonItem alloc] initWithTitle: #"Blabla" style: UIBarButtonItemStylePlain target: self action: #selector(myMethod:)];
Finally, I found a way to do it, not the prettiest, but it works.
In the custom toolbar class I created in its layout method a UITapGestureRecognizer to handle taps. I've set the cancelsTouchesInView to false and in the
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
method I'm returning true only for my toolbar's subviews.
This way the original target and action of each UIBarButtonItem remains the same and the supplementary code to handle my popup is the action of the UIGestureRecognizer.
Another problem was to distinguish between the tapped items on the toolbar (the tapped view in touch.view is some undocumented view, yay), eventually I did it with some BOOL iVars.
I hope this will help somebody with the same problem.

KVO with two UIButtons

I have a custom UITableViewCell subclass that gets presented in a UITableView in a UIPopoverController. The UIPopoverController is presented from a UIBarButtonItem.
When selections in the UITableViewCell are made, I send a NSNotification to the UIViewController class that is presenting the UIPopoverController. The selections in the table update my view in my viewController.
Now, there is a requirement to have another UIBarButtonItem that does EXACTLY the same thing as one of the buttons in the UITableViewCell in the popover. Basically the use case is that this feature seems to be the most commonly used feature in our popover and they want an easy way to just turn it on and off from another button.
So what I did was create a new UIBarButtonItem, and have a target attached to it:
- (void)FilterOn:(id)sender {
isFilterOn = !isFilterOn;
if ([sender isKindOfClass:[UIBarButtonItem class]]) {
UIBarButtonItem *filter = (UIBarButtonItem *)sender;
if (isFilterOn) {
[filter setTitle:#"Filter On"];
[self DoFilter];
}
else {
[aboutMeBBI setTitle:#"Filter Off"];
[self ClearFilter];
}
}
}
So this part works. It updates the model, the title of the button changes. The problem is, let's say I turn filter on, then in the popover, I turn the filter off. I pass the notification to my viewController class to its normal update method that handles filtering and a bunch of other stuff. I added this simple snippet to when the filter button is pressed from the popover:
- (void)FilterSortOptionDidSelect:(NSNotification *)notification {
NSDictionary *userDict = [notification userInfo];
NSInteger theTag = [[userDict objectForKey:#"CellTag"] integerValue];
switch (theTag) {
case FILTER: {
// update Model
[self.FilterBarButtonItem setTitle:#"Filter off"];
}
break;
default:
break;
}
}
This isn't quite what I want though since if I click back on the filter button since for starters, if I click back on the Filter button, it'll still say Filter Off, and do the action for Filter Off, and then if I click it again, it'll do Filter on actions. I try to fake it in the switch statement by changing the title, but that isn't really what I want to do. I read a little about key value observing and I wasn't sure if I could use something like that here, to register my buttons state with that of a button in a UITableViewCell subclass in a UIPopoverController. If anyone has any ideas that would be great. Thanks.

How to dismiss keyboard when using DecimalPad

I have a UITableView with a custom cell that has a TextField. I have the DecimalPad comes up, and as we all know, there is no done key. I previously had resolved this type of issue when I had a "Decimal only" textfield on a normal UIView by handling the TouchesEnded event and then checking to see if the TextField was the first responder and if so, it would then resign, but if that technique could work now then I'm not able to figure out who's TouchesEnded I should be using (The UIView that everything is presented on, the UITableView, the Cell, the CellControler, the TextField.. I think I've tried everything).
I'm hoping there's another, cleaner way of dealing with this.
Anyone?
I think David has the best idea - here is some Monotouch code to get you started. You will need to put this in the View Controller where the decimal pad is being shown:
UIView dismiss;
public override UIView InputAccessoryView
{
get
{
if (dismiss == null)
{
dismiss = new UIView(new RectangleF(0,0,320,27));
dismiss.BackgroundColor = UIColor.FromPatternImage(new UIImage("Images/accessoryBG.png"));
UIButton dismissBtn = new UIButton(new RectangleF(255, 2, 58, 23));
dismissBtn.SetBackgroundImage(new UIImage("Images/dismissKeyboard.png"), UIControlState.Normal);
dismissBtn.TouchDown += delegate {
textField.ResignFirstResponder();
};
dismiss.AddSubview(dismissBtn);
}
return dismiss;
}
}
If you're targeting iOS 4.0 or greater you can create an inputAccessoryView containing a Done button to attach to the keyboard that will dismiss the keyboard when tapped. Here is an example from the documentation on creating a simple inputAccessoryView.
You could dismiss it when the user taps on the background; I think that's the most intuitive way.
In Interface Builder, change your View's class to UIControl. This is a subclass of UIView, so your program will work the same way, but you also get the standard touch events.
From here it's simple, create a method for the Touch Down event:
[numberField resignFirstResponder]
Of course it might be slightly different with MonoTouch -- unfortunately I don't know much about it, but wanted to help.
Hopefully you can use the concept, and modify your code accordingly.
Or you may just add some gesture to your main view.
For example:
//Just initialise the gesture you want with action that dismisses your num pad
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
UISwipeGestureRecognizer *swipeToHideNumPad = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(hideNumPad:)];
swipeToHideNumPad.delegate = self;
swipeToHideNumPad.direction = UISwipeGestureRecognizerDirectionDown;
[swipeToHideNumPad setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:swipeToHideNumPad];
}
//action
- (void)hideNumPad:(UIGestureRecognizer *)gestureRecognizer
{
[self.amountTextField resignFirstResponder];
}