Access UINavigationViewController from UIImageView class - ios

I have a UIImageView with a custom class. When the image is pressed the class should push a new view controller, however I don't seem to be able to get a reference to the current UINavigationController. I would usually do self.navigationController, but here I can't.
I tried the following code but it doesn't work:
[self.window.rootViewController.navigationController pushViewController:browser animated:YES];

Give your Custom Image View a delegate:
#protocol CustomImageViewDelegate;
#interface CustomImageView : UIImageView
#property (weak, nonatomic) id<CustomImageViewDelegate> delegate;
#end
#protocol CustomImageViewDelegate
- (void)imageViewPressed:(CustomImageView *)imageView
#end
Make you view controller the delegate. When the image is pressed, you do [self.delegate imageViewPressed:self.
Your view controller will have the implementation:
- (void)imageViewPressed:(CustomImageView *)imageView
{
[self.navigationController pushViewController:browser animated:YES];
}
Or give your view a Navigation Controller property:
#interface CustomImageView : UIImageView
#property (weak, nonatomic) UINavigationController navigationController;
#end
Then you can use [self.navigationController pushViewController:browser animated:YES] directly on your Custom Image View.
You'll have to set the navigationController property, iOS won't do it for you.
On your controller add the line
self.yourCustomImageViewProperty.navigationController = self.navigationController;
This is a very basic response, but I hope it steers you in the right direction.

First make UIImageView to UserInteractionEnabled = YES.
Check that self.window.rootViewController.navigationController is
nil or not .

If the root view controller is already a navigation controller, then you could do this:
UINavigationController *nav = self.window.rootViewController;
[nav pushViewController:browser animated:YES];

Related

Delegate not called after dismissing controller

I have a Controller A and there is a UIButton, which on click I am presenting a new Controller B. But the problem is that the controller B is first embedded with a NAV. So ultimately I am presenting the UINavigationController.
Now there is a UIButton in Controller B on which the controller will dismiss and a delegate should be passed on controller A with some message
Controller A UIButtonCode
- (IBAction)summaryButtonClick:(id)sender {
UIStoryboard* storyBoard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController* summaryVC=[storyBoard instantiateViewControllerWithIdentifier:#"SummaryNavVC"];
[self presentViewController:summaryVC animated:YES completion:nil];
summaryVC=nil;
}
Now Controller B
.h file
#import <UIKit/UIKit.h>
#protocol SummaryViewWhatsNewDelegate <NSObject>
#required
- (void) SummaryViewWhatsNew:(NSString*)title;
#end
#interface SummaryViewController :
UIViewController<UITableViewDataSource,UITableViewDelegate>
{
id <SummaryViewWhatsNewDelegate> _delegate;
}
#property (nonatomic,strong) id delegate;
#property (weak, nonatomic) IBOutlet UITableView *summaryTableView;
- (IBAction)closeSummaryView:(id)sender;
#end
.m
//Button Click
[self dismissViewControllerAnimated:YES completion:^{
[_delegate SummaryViewWhatsNew:#"Sales Triggers Filter"];
}];
I have already made the implementation of delegate in my Controller A
.h
#interface ControllerA : UIViewController<SummaryViewWhatsNewDelegate>
.m of Controller A
#pragma mark -ControllerB Delegate
-(void)SummaryViewWhatsNew:(NSString *)title{
NSLog(#"Delegate Called");
}
In this case I know I haven't provided the delegate.self part as I am presenting the NAV controller and not the Controller B
So I made a Object in viewDidLoad and Controller *B and set the delegate to self. But it doesn't work and delegate is never called
On the other hand if I only present the Cntroller B without Navigation and just before presenting I keep the b.delegate=self, it works.
Another alternate can be firing Notifications. But I want to work with delegates.
So is there any way to call the delegate of the presented view controller which is embedded by Nav. Any help will be highly appreciated.
Well I got the answer
We have to fetch the Controller object from NAV
Where I a presenting I just need to add these lines and it worked
UIStoryboard* storyBoard=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController* summaryVC=[storyBoard instantiateViewControllerWithIdentifier:#"SummaryNavVC"];
//Add These lines in order to get the object of Controller B.
// SummaryViewController is my Controller B
SummaryViewController* summary=[[summaryVC viewControllers] objectAtIndex:0];
summary.delegate=self;
[self presentViewController:summaryVC animated:YES completion:nil];
And it worked.

How to push or present UIViewcontroller or storyboard from UIView subclass?

What I did:
I am using scrollview to view some UIView(s), with paging enabled.
In last page in subview of scrollView I added a button.
I also wrote a function which is in subclass of UIView ,which is invoked when we press that button.
I want to view storyboard when I press that button.
You need to implement protocol method for custom UIView class.
For example;
#import <UIKit/UIKit.h>
#protocol YourCustomViewDelegate <NSObject>
- (void)buttonTapped;
#end
#interface YourCustomView : UIView
#property (nonatomic, strong) id< YourCustomViewDelegate > delegate;
#end
And the .m file you can call buttonTapped delegate method.
- (void)myCustomClassButtonTapped:(id)sender
{
[self.delegate buttonTapped];
}
For proper work;
set your custom view delegate to self in your custom view controller.
add buttonTapped method to that view controller
And do what you want in that method. Present/Push view controllers like the other answers explained.
Edit
I will try to illustrate very simple usage of protocols, hope it will help you.
#import "MyViewController.h"
#import "YourCustomView.h"
#interface MyViewController ()<YourCustomViewDelegate> // this part is important
#end
#implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
YourCustomView *customView = // initialize your custom view, I suppose that you already did it
customView.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)buttonTapped
{
YOUR_VIEW_CONTROLLER_CLASS *viewCon =[storyboard instantiateViewControllerWithIdentifier:#"mainVC"]; //mainVC is just a example and u will have to replace it with your viewController storyboard id
//Pushing VC
[self.navigationController pushViewController:viewCon animated:YES];
}
Take a look at this
YourViewController *obj=[[YourViewController alloc]init];
UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:obj];
[[[UIApplication sharedApplication]keyWindow].rootViewController presentViewController:nav animated:YES completion:NULL];
try like this
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController* initialView = [storyboard instantiateInitialViewController];
Firstly you need to set a storyboard Id to your ViewController, namely "mainVC". Then you could pus/present it using below code :-
YOUR_VIEW_CONTROLLER_CLASS *viewCon =[storyboard instantiateViewControllerWithIdentifier:#"mainVC"]; //mainVC is just a example and u will have to replace it with your viewController storyboard id
//Pushing VC
[self.navigationController pushViewController:viewCon animated:YES];
//OR presenting VC
[self presentViewController:viewCon animated:YES completion:nil];
Also in case if you want your another storyboard to be initiated then below,
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil]; //Change MainStoryboard with your storyboard id
hope this will help
the way i perceive your question is
->Rightnow your inside you are in UIView class and inside it there is a button by clicking it you want to push or present a ViewController and offcourse from inside your UIView class you cant push or present your view Controller. So
you can do one simple thing first inside action method make a ref(forward declaration) or you can make a whole new object of your ViewController class in which your UIView is present right now , then call a function(which exist in your ViewController) like
//function inside your uiview calss
- (void)btnaction
{
[_objCSInformationViewController pushViewController];
}
// function inside your view controller
-(void)pushViewController
{
yourViewController *objViewController = [[yourViewController alloc]initWithNibName:#"yourViewController" bundle:nil];
[strong.navigationController pushViewController:objViewController animated:YES];
}

UIPopoverview for iPhone,iOS 7

I need popover view. i followed this instructions.
Init: Create two UIViewController in storyboard.
lets say FirstViewController which is normal and SecondViewController Which we make Popup.
Model Segue: Put UIButton In FirstViewController and create a segue on this UIButton to SecondViewController as model segue.
Make Transparent: Now selet UIView (UIView Which is created by default with UIViewController) of SecondViewController and change its background color to clear color.
Make background Dim: Add a UIImageView in SecondViewController which cover hole screen and sets its image to some dimmed semi transparent image. You can get a sample from here : UIAlertView Background Image
Display Design: Now Add a UIView and make and kind of design you want to show. Here I have shown screen shot of my storyboard.
Here I have add segue on login button which open SecondViewController as popup to ask username and password
Important: Now that main step. We want that SecondViewController dont hide FirstViewController completely. We have set clear color but this is not enough. By default it add black behind model presentation So we have to add one line of code in viewDidLoad of FirstViewController. You can add it at other place also but it should run before segue.
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
Dismiss: When to dismiss is depend on you. This is a model presentation so to dismiss we do what we do for model presentation:
[self dismissViewControllerAnimated:YES completion:Nil];
But am USING NAVIGATION CONTROLLER,, for that transparent background is not coming?????
Kindly help me..!!!! My screen shot is below.
create one view controller in freeform mode just like following image
in your first view controller add the one UIButton just like the following image
in your first view controller.h add the following line
#import "UIPopoverController+iPhone.h"
#interface first view controller : UIViewController<UIPopoverControllerDelegate>
#property (nonatomic,strong) UIPopoverController *popOver;
#property (strong, nonatomic) IBOutlet UIButton *popbtn;
in your first view controller.m add the following line to the button action method
- (IBAction)popButton:(UIButton *)sender
{
UILabel *showlblView=[[UILabel alloc]init];
showlblView.frame=CGRectMake(10, 10, 250, 40);
showlblView.text=#"Gopi";
showlblView.textColor=[UIColor whiteColor];
showlblView.textAlignment=NSTextAlignmentCenter;
final *vc=[[final alloc] init];
[vc.view addSubview:showlblView];
self.popOver=[[UIPopoverController alloc]initWithContentViewController:vc];
[self.popOver setPopoverContentSize:CGSizeMake(300, 200)];
CGRect popoverframe=CGRectMake(self.popbtn.frame.origin.x, self.popbtn.frame.origin.y, self.popbtn.frame.size.width, self.popbtn.frame.size.height);
[self.popOver presentPopoverFromRect:popoverframe inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
here ur NSObjet class file UIPopoverController+iPhone.h
.h file
#import <UIKit/UIKit.h>
#interface UIPopoverController (iPhone)
+ (BOOL)_popoversDisabled;
#end
.m file
#import "UIPopoverController+iPhone.h"
#implementation UIPopoverController (iPhone)
+ (BOOL)_popoversDisabled {
return NO;
}
#end
the full project code is available at the following link :
https://www.sendspace.com/file/ktie4t
i had the same problem and didn't find solution how to solve it with segue on storyboard, but programmatically it's work fine, when i presenting second controller on first controller (that pushed with navigationViewController). if it's not critical for you, try this:
+ (void)showWithParent:(UIViewController *)parentController {
static SomeViewController *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
singleton = [storyboard instantiateViewControllerWithIdentifier:#"SomeViewControllerID"];
});
[parentController presentViewController:singleton animated:YES completion:nil];
}
or just:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *secondController = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID"];
[firstController presentViewController:secondController animated:YES completion:nil];

Objective - C: Hidding a button through a delegate

I have two views a levelComplete view and a levelSelector view. What I would like to do is when the levelComplete shows or the ViewDidLoad occurs on that view I would like to send a delegate to the level selector to show a button in the view and then make that button UserInteractionEnabled so then I will then be able to programme that button to do something if its not hidden.
You want to necessarily do it via a delegate. Coz you can do it in a simpler way as well. When you call your secondView, just tell your button to hide. So your modified code to calling the second view controller becomes:
-(IBAction)passdata:(id)sender {
secondview *second = [[secondview alloc] initWithNibName:nil bundle:nil];
self.secondviewData = second;
sender.hidden=YES;
secondviewData.passedValue = textfield.text;
[self presentModalViewController:second animated:YES];
}
And then you can set it to visible when your view loads up again using viewDidLoad. I can tell you how to do it via delegates if you need. Lemme know what works best.
EDIT - Solution by Delegates
Your secondView's Header file will be as follows:
#protocol SecondViewHandlerDelegate <NSObject>
- (void)viewHasBeenLoaded:(BOOL)success;
#end
#interface secondview :UIViewController {
IBOutlet UILabel *label;
NSString *passedValue;
}
#property (nonatomic, retain)NSString *passedValue;
-(IBAction)back:(id)sender;
#end
Then, in the implementation file of secondView(.m), synthesise the delegate first by #synthesize delegate; . After this, in your viewDidLoad of secondView, add the following line:
[[self delegate] viewHasBeenLoaded:YES];
That should be enough for your secondView. Now onto the firstViewController, perform the following steps:
In the header file (.h), import your second view and implement the protocol:
#interface ViewController :UIViewController <SecondViewHandlerDelegate>{
..
..
}
In the implementation file (.m) of your firstViewController, implement this method:
- (void)viewHasBeenLoaded:(BOOL)success
{
NSLog("Delegate Method Called");
[myButton setHidden:YES];
}
And finally, in your code when you call the secondView, add this line:
secondview *second = [[secondview alloc] initWithNibName:nil bundle:nil];
second.delegate = self;
...
That should solve your purpose. I'd appreciate if you could mark the answer as correct as well. Thanks :)

Pushing UIViewController crashes

I have the following code pushing a UIViewController. This code is a target method that gets executed when a UIButton is pressed:
-(void)pushNavigationController
{
ParameterListerViewController *plvc = [[ParameterListerViewController alloc] init];
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:plvc];
self.navigationController.navigationBarHidden = YES;
plvc.numberOfParameters = [[numberOfTrialsField text] intValue];
NSLog(#"about to push the navigation controller");
[self.navigationController pushViewController:nvc animated:YES];
}
It gets until the NSLog statement, but after that, the view controller never gets pushed and the app just crashes. Here is the header file of ParameterListerViewController:
ParameterListerViewController.h
-------------------------------
#interface ParameterListerViewController : UIViewController<UITextFieldDelegate>
{
UIScrollView* scrollView;
}
#property(nonatomic) NSInteger numberOfParameters;
#end
Here's the header file which contains the UIButton and the respective target method which contains the code for pushing the navigation controller.
SettingsViewController.h
------------------------
#interface SettingsViewController : UIViewController <UITextFieldDelegate, UIPickerViewDelegate, UITableViewDelegate, UITableViewDataSource>
{
id <SettingsViewDelegate> delegate;
}
#end
And here's the header file of a class object that DOES GET PUSHED:
#interface ItemViewController : UITableViewController
{
}
#end
Any suggestions?
Your nav controller's view has to be in the view hierarchy.
Unless the nav controller is set as the rootViewController of a UIWindow, it needs to be explicitly added.
Try this:
[self.view addSubview:self.nvc.view];
If this is the case, you won't need to do the pushViewController - the plvc will already be visible.

Resources