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
Related
My first view in the viewDidLoad has the following code
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Dialpad" bundle:nil];
self.vc = [sb instantiateViewControllerWithIdentifier:#"DialpadBoard"];
self.vc.delegate = self;
The header file contains the definition of the view controller
#property (nonatomic, retain) DialpadTableViewController *vc;
after catching an event the view loads a new modal view
- (void)handleEvent:(UIGestureRecognizer*)recognizer {
[self presentViewController:self.vc animated:YES completion:NULL];
}
The view also contains the method to dismiss the modal view:
- (void) dialpadControllerDidCancel:(SearchDialpadTableViewController *)controller {
[self dismissViewControllerAnimated:YES completion:nil];
}
The last method never gets called.
The problem is that the modal view when it is loaded has nil self.delegate. The new modal view is loaded from the storyboard as seen below. Why the delegate is nil? I cannot how a segue since the view is in another storyboard.
you can try this
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Dialpad" bundle:nil];
UINavigationController *nav= [sb instantiateViewControllerWithIdentifier:#"DialpadBoard"];
((SearchDialpadTableViewController *)[nav viewControllers][0]).delegate = self;
[self presentViewController:nav animated:YES completion:NULL];
Since we have the nav let's take the first controller and assign the delegate
the trick ;)
((SearchDialpadTableViewController *)[nav viewControllers][0]).delegate = self;
Does SearchDialpadTableViewController define a delegate protocol and does it have a property that is specific to that protocol?
The header for that file should look something like:
#protocol ViewControllerDelegateProtocol <NSObject>
- (void)dialpadControllerDidCancel:(SearchDialpadTableViewController *)controller;
#end
#interface ViewController : UIViewController
#property (weak, nonatomic) id<ViewControllerDelegateProtocol> searchPadDelegate;
#end
Then when the user taps Done which is I'm assuming what you're trying to do (send a delegate message when that happens). You would write something like
- (IBAction)donePressed:(id)sender
{
if ([self.searchPadDelegate respondsToSelector:#selector(dialpadControllerDidCancel)]) {
[self.searchPadDelegate dialpadControllerDidCancel:self];
}
}
you must be certain, that self.vc is a class, that you expected. It can be also NavigationController
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 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];
I'm trying to change the ViewController when an area in a pic is pressed.
I tried doing this :
-(void)openDrawer{
UIStoryboard *mStoryBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc =[mStoryBoard instantiateViewControllerWithIdentifier:#"DrawViewController"];
[self.navigationController pushViewController:vc animated:YES];
}
but self.navigationController does not exist, that is understandable, but I can not find a way to get a the current viewController with in the Image
I tried putting it in a different class, delegating from the viewController of the current view.
-(void) changeChangeViewToName:(NSString *)name{
UIStoryboard *mStoryBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc =[mStoryBoard instantiateViewControllerWithIdentifier:name];
[self.navigationController pushViewController:vc animated:YES];
}
This works from inside the viewController but I can't call the function from inside the Image.
Post a notification from the class (image?) that decides it wants the new view controller displayed. Listen for that notification in the existing view controller that is capable of doing the push.
Phillip Mills is right. You could also use the delegate pattern:
Create a protocol for objects that should be able to perform the desired action:
#protocol YourImageDelegate
-(void)touchUpInsideArea;
#end
Add this method to your view controller:
-(void)touchUpInsideArea {
[self openDrawer];
}
Set up your view controller to conform to the protocol:
#interface YourViewController : UIViewController
And don't forget to include your protocol in both files: the view controller class and the image class.
I'm using a UIStoryBoard to allow the FirstViewController to add the view of second ViewController as a subview. On removing the sub view using the following method
FirstViewController.m
- (IBAction) btnMoveTo:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"Second"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:vc animated:NO];
}
SecondViewController.m
-(void)viewDidLoad{
self.view.opaque = YES;
self.view.backgroundColor = [UIColor clearColor];
}
- (IBAction) withDraw:(id)sender{
[self.view removeWithZoomOutAnimation:2 option:nil];
}
When I access the withDraw Function, the view of the SecondViewController is removed and firstViewController is back. However when I use the button to access the - (IBAction) btnMoveTo:(id)sender function. It doesn't work. Nothing really happens. Any suggestions or help would be greatly appreciated.
You are confusing views with view controllers. View controllers are objects that control views, so for the first line you wrote,
I'm using a UIStoryBoard to allow the FirstViewController to add the view of second ViewController as a subview. On removing the sub view using the following method
you cant add a view controller as a subview of another view controller. You present a view controller that manages its own views, and you can add UIViews as subviews of a UIViewController. A UIViewController manages UIViews.
The problem you are having with the code you posted, is that when you trigger the withDraw: function, you are removing the view of the view controller. Not the view controller itself. You need to dismiss the SecondViewController to gain access of the FirstViewController again.