Remove Cancel Button in UIImagePickerControler--iOS 5.0 - ios

I have an App where it displays a UIImagePickerController on launch. The controller displays the cancel button, but there is nothing to cancel to. Is there any way to remove the button?
NOTE: This is not a duplicate of Can the Cancel button be removed from a UIImagePickerController in OS 3.2?. The answer there for iOS 3.2 does not work for me in iOS 5.

I try to put UIImagePickerController not modally, but in original way (as we do it with ordinary custom UIViewController). So, I need no the cancel button in the UINavigationBar.
There are no documented ways to remove the cancel button. But here I found some idea.
I just added this code in my AppDelegate.m file:
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
for (UINavigationItem *item in navigationController.navigationBar.subviews) {
if ([[item title] compare:#"Cancel"] == 0) {
UIButton *button = (UIButton *)item;
[button setHidden:YES];
}
}
}
So the cancel button is hidden now. But if you pick some folder in you photo albums the next view will be with that button (and it is not hidden).
Then I tried to add code like this:
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
for (UINavigationItem *item in navigationController.navigationBar.subviews) {
if ([[item title] compare:#"Cancel"] == 0) {
UIButton *button = (UIButton *)item;
[button setHidden:YES];
}
}
}
I get the cancel button is hidden in all navigation stack inside UIImagePickerController's navigation.
But while the new view is appearing (animation transition) the cancel button is appearing too.
I don't know how to fix this problem.
However I think that it is a tricky and inefficient approach. Because it can break your application in the future iOS updates. So you can use the answer to that question. But it is different approach at all.
P.S. Sorry for my language.

For iOS 7 and 8 the above solution will not work,
There is small change that should be done because we cannot use navigation item from navigation bar. The following will work like a charm
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
viewController.navigationItem.rightBarButtonItems = nil;
}
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
viewController.navigationItem.rightBarButtonItems = nil;
}

Related

UITableView reloads data, when pushing a new viewController

I have the following VC hierarchy: ParentViewController -> Navigation Controller(child VC) -> ViewController(with UITableView).
I am meeting the following issue:
In UITableViewDelegate.didSelectRowAtIndexPath, the app is pushing a new ViewController on the stack. The problem is that at this stage, the table view is automatically reloaded, without any explicit call to reloadData. This fact creates several issues, for example on return to the screen(with Back button) the table view is scrolled at the beginning instead of being focused on the selected row.
Could you please help me find why is it doing like so, is it a bug, or how to fix the issue?
UPDATE: I have just tested the same case on iOS 7.1 and there is no issue like that, I mean pushing a viewController, than poping back to the viewController containing the UITableView does not loose focus of the selected row.
hope this could help you.
My solution is to use navigationviewcontroller delegate, save selection when will push another one, and set back when pop back.
My sample code(I have set table view controller as delegate)
static NSIndexPath* path = nil;
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (viewController == self)
{
[self.tableView reloadData];
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
path = self.tableView.indexPathForSelectedRow;
}

Xcode: Detecting when a navigation controller implemented "back button" is pressed

Scenario
I have an app with a navigation controller. When the navigation controller pushes another controller onto the stack, in the upper left corner of the screen it shows the back button "<(title of the last view controller)".
What I need
I need something like (pseudo code)...
-(void)detectedBackButtonWasPushed {
NSLog(#"Back Button Pressed");
//Do what I need done
}
Question
Because this button is created by the navigation controller and I did not create this button in storyboards, how do I get the back button 'hooked up' to a method like this?
examples of what Ive tried for Oleg
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"notification"];
if (viewController == vc) {
NSLog(#"BACK BUTTON PRESSED");
}
}
Is this how I'm supposed to do it? Cause this doesn't work.
Use viewWillDisappear to detect this.
-(void) viewWillDisappear:(BOOL)animated
{
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
{
[self backButtonPressed];
[self.navigationController popViewControllerAnimated:NO];
}
[super viewWillDisappear:animated];
}
-(void)backButtonPressed
{
NSLog(#"YEA");
}
Previously, I have solved this by setting the navigationBar leftItem to be a back button with a custom selector that dismisses the view along with whatever else it needed to do.
I might also suggest looking at the back button item and adding a target:self that is called on touch.

EGOPhotoViewer and NavigationController

I'm having a problem with EGOPhotoView library in my iOS app, and I hope someone of you can help me.
My app uses a NavigationController, but does not display the NavigationBar, because the navigation is managed my some custom control. The problem is when I show an image gallery with the EGOPhotoView library, which shows a NavigationBar appearing on tap: when I pop the EGOPhotoViewController, the NavigationBar is still displayed, but I don't want.
Can someone help me to fix this problem?
Thanks
You can set one of your classes (probably your app delegate) to be the navigation controller's delegate. Then, when the EGOPhotoViewController is popped, you can hide the navigation bar. E.g.
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
if ([navigationController.topViewController isKindOfClass:[EGOPhotoViewController class]])
{
[navigationController setNavigationBarHidden:YES animated:YES];
}
}

Which method is called when back button clicked in navigation controller?

I want to save DB when the back button clicked in navigation controller.
so I would insert code in method.
What method is called when back button clicked in navigation controller?
To do what you asked, look at the UINavigationControllerDelegate protocol, namely the method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
when the viewController argument is no longer your view controller then you should save.
However, doing so on viewWillDisappear: might be a better (and much simpler) idea.
Maybe it's not appropriate use, but that worked for me. Don't forget to set UINavaigationController delegate.
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
NSLog(#"from VC class %#", [fromVC class]);
if ([fromVC isKindOfClass:[ControllerYouJustPopped class]])
{
NSLog(#"Returning from popped controller");
}
return nil;
}

UIImagePickerController: is it possible to set overlay view only in editing mode after capture?

I have AllowEditing set to true, and after the image is captured, I want to give additional instructions in the editing screen to crop out part of the image. Is that possible?
The UIImagePickerViewController is in fact a UINavigationController. This gives you the ability to track on which step in the UINavigationViewController you are, so you can set the overlay view only when the second view controller is reached.
In brief:
- UIImagePickerController.delegate = self
- make self conform to the UINavigationControllerDelegate protocol
- implement next method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([navigationController.viewControllers indexOfObject:viewController] == 1)
{
// If second UIViewController, set your overlay.
}
}
Dires De Smet, your solution is good, but not good enough, cause you don't really know for sure what is your current view controller's index (of curse you can find it, but its ugly)
So i come with new if condition, check it out:
Assuming self is your current UIViewController and not some NSObject subclass,
if self it is NSObject subclass, so use:
UIViewController *currentViewController=(UIViewController *)[[[[[[[UIApplication sharedApplication]delegate]window]rootViewController]navigationController]viewControllers]lastObject];
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (![viewController isKindOfClass:[self class]]){
//do your thing...
}
}

Resources