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];
Related
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.
I looked at many stackoverflow answers and tried most of them. May be I am doing something wrong but if I can get clarified, it will be wonderful.
My viewcontroller LoginViewController has a method which gets called and custom alertview which is a uiview is shown to user. After user enters 4 digit pin, I need to call another view controller from that custom alertview (uiview).
My current setup is:
LoginViewController.h:
#import "LoginPinAlertView.h"
#interface LoginViewController : UIViewController <LoginPinAlertViewDelegate,... > {
LoginPinAlertView *customAlertView;
}
LoginViewController.m:
-(void) viewDidLoad {
...
customAlertView.myLoginVC = self;
}
Inside my UI VIew (which a customer alert view)
LoginPinAlertView.h
#class LoginViewController
...
#property (nonatomic, retain) LoginViewController *myLoginVC;
LoginPinAlertView.m
....
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
DestinationViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MyDestViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self.myLoginVC presentViewController:vc animated:NO completion:NULL];
}
...
But this is not working right now. What my requirement is, from UI View (which is not part of any contorller because this is custom alert view which many controllers are using), I wish to push/present another view controller.
hope this will help you ,
you cannot push/present view controller from a uiview class for it. you should check out this answer , https://stackoverflow.com/a/26011073/3767017
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];
}
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];
I have a navigation based application.On click of a button on the navigation bar in the first screen , I am able to push another view controller as follows :
-(void) buttonClicked:(id)sender
{
UIViewController* mv = [[SecondViewController alloc] init];
[[self navigationController] pushViewController:mv animated:YES];
}
Now i have a UIView(separate .h and .m files) as part of the first screen. On click of a button in the UIView, i want to push the SecondViewController.
I have tried the following :
UIViewController* mv = [[SecondViewController alloc] init];
UIViewController * home=[[FirstViewController alloc]init];
[[home navigationController] pushViewController:mv animated:YES];
It doesnt work!! Kindly help
UIViewController* mv = [[SecondViewController alloc] init];
UIViewController * home=[[FirstViewController alloc]init];
[[home navigationController] pushViewController:mv animated:YES];
The problem here is that home isn't part of the navigation stack, so [home navigationController] is surely nil. I'm not quite clear on what you're trying to do here, but just creating a view controller doesn't mean that it's actually part of the view controller graph.
Why would it work? Randomly creating view controllers whose view is not even visible, is not the solution. You can either keep a reference to the VC in the view like this:
#imlementation ViewController
- (id) init
{
// ...
aView = [[CustomView alloc] init];
aView.viewController = self;
// ...
}
#end
#interface CustomView
#property (assign) ViewController *viewController;
#end
Or you can search the responder chain at runtime:
UIResponder *next = [view nextResponder];
while (next)
{
if ([next isKindOfClass:[ViewController class]])
{
break;
}
next = [next nextResponder];
}
And now "next" will contain the view controller (or nil if it can't be found).
Try using the same navigationController to push view, this keeps the same stack of ViewControllers.
UIViewController* mv = [[SecondViewController alloc] init];
[[self navigationController] pushViewController:mv animated:YES];
[mv release];
I see your problem now! You need to #import your FirstViewController, then #class it. Then do your push.
So:
//.h
#import "FirstViewContoller.h"
#class FirstViewController;
#interface...
//.m
-(void)return {
FirstViewController *firstview = [[FirstViewController alloc]init(withnibname:)];
[firstView.navigationController pushViewController: firstView.navigationController.topViewController animated: TRUE];
}
If I am not wrong, your UIView though is in separate files, is still added to the screen from a UIViewController class.
Simply, post a notification from UIView to your FirstViewController class where you have access to the navigation controller. Then push the SecondViewController from there.
You Can use this. It Works very well for me:-
Firstly Create Object of AppDelegate in UIView Class and initialize it. Then create Navigationcontroller object in Appdelegate.h :-
#property(strong,nonatomic) UINavigationController *navControl;
In your UIView Class implement this code where you want to push :-
ViewController *objview = [[ViewController alloc]init]; [appDelegate.navControl pushViewController:objview animated:YES];