Switch view to another view on storyboard - ios

I am new in iOS programming.
What I am trying to do is:
I have some views in a storyboard and I'd like to switch between the views programatically. For example, when a button is clicked, I call a method and I want to change views here (I can call the method successfully). The buttons are also created programatically in different positions.
I have searched and I think it happens with NavigationController. I have a navigation controller which I created like so: menu Editor -> Embed In -> NavigationController. How could I do this using this NavigationController?
#Madhu and #Dilip ,I found a solution with xib filed class
icerik *secondViewController = [[icerik alloc] initWithNibName:#"icerik" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
navigationController.topViewController.title = #"SecondViewController";
//[self presentModalViewController:navigationController animated:YES];
if([self respondsToSelector:#selector(presentViewController:animated:completion:)])
[self presentViewController:navigationController animated:YES completion:^{/* done */}];
else if([self respondsToSelector:#selector(presentViewController:animated:)])
[self presentModalViewController:navigationController animated:YES];
I have a class with xib file named icerik, I solved it like this. It is opening but when I want to turn back, What can I do it ?

You can create btn using this code:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.view addSubview:button];
and for going to another vc use this code,if you want navigation bar:
-(void)aMethod
{
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:SecondViewController];
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
navigationController.topViewController.title = #"SecondViewController";
[self presentModalViewController:navigationController animated:YES];
}
Else use this code:
-(void)aMethod
{
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self presentModalViewController:secondViewController animated:YES];
}
And for come back to frist vc fromm second vc add this code in second vc.
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(backAction:)];
self.navigationItem.leftBarButtonItem = closeButton;
}
- (void)backAction:(id)sender {
[self dismissModalViewControllerAnimated:NO];
}

If your new to Objective-c first go with Views/ViewControllers. i.e. use addSubView property of UIView
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(10, 0, 250.0, kCCCellHeaderHeight)];
[subView setBackgroundColor:[UIColor redcolor]];
[self.view addSubview:subView];
If your little known of UINavigationCOntroller Use pushViewController
CCFilteredVideosController *filteredController = [[CCFilteredVideosController alloc] initWithNibName:#"CCFilteredVideosController" bundle:nil];
[self.navigationController pushViewController:filteredController animated:YES];
[filteredController release];

Related

Different navigation bar behaviour between CABTMIDILocalPeripheralViewController and CABTMIDICentralViewController

I am struggling to understand why the following views, one for CABTMIDILocalPeripheralViewController and the other for CABTMIDICentralViewController show different behaviour in my iOS app (written in Objective-C)
- (IBAction)configureCentral:(id)sender
{
CABTMIDICentralViewController *viewController = [CABTMIDICentralViewController new];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; // this will present a view controller as a popover in iPad and modal VC on iPhone
viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(doneAction:)];
navController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popC = navController.popoverPresentationController;
popC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popC.sourceRect = [sender frame];
viewController.preferredContentSize = CGSizeMake(320., 400.);
popC.backgroundColor = [UIColor darkGrayColor];
viewController.view.backgroundColor = [UIColor darkGrayColor];
UIButton *button = (UIButton *)sender;
popC.sourceView = button.superview;
[self presentViewController:navController animated:NO completion:nil];
}
Opens a popup view on an iOS device, which does not show any 'done' button to dismiss the view.
CABTMIDICentralViewController shows no button to close/dismiss the view
While on an iPad tapping outside the view will close it, on an iPhone the view takes the size of the screen and exiting/closing becomes impossible.
The same code used for the CABTMIDILocalPeripheralViewController works as expected.
- (IBAction)configureLocalPeripheral:(id)sender
{
CABTMIDILocalPeripheralViewController *vController = [[CABTMIDILocalPeripheralViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vController];
vController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(doneWithPeripheral:)];
navController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popC = navController.popoverPresentationController;
popC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popC.sourceRect = [sender frame];
vController.preferredContentSize = CGSizeMake(320., 400.);
popC.backgroundColor = [UIColor grayColor];
vController.view.backgroundColor = [UIColor darkGrayColor];
UIButton *button = (UIButton *)sender;
popC.sourceView = button.superview;
[self presentViewController:navController animated:NO completion:nil];
}
CABTMIDILocalPeripheralViewController has a 'done' button
What is going wrong here? I have tested to make the views wider to see whether available space in the Navigation bar would have caused this.
Thanks.

Present view controller before initial view controller is shown

I have an app that has the following structure:
The main view controller is a tab bar view controller that has 4 tabs.
Users can only access these view controllers when they are logged in. When app launches, it loads it's initial view controller (the tab bar one), and then I check to see if user is authenticated. If it's not, I present a login view controller.
The problem I'm having is that when app launches, it's loading the tab bar controller and from that controller it presents the login view controller, but it does so with a small time window that shows the tab bar controller's view on the screen, before the login's view. I need to directly present the login view, from the tab bar controller, but without showing tab bar controller's view in that small time interval, as it's not user friendly.
I read some answers on stackoverflow about presenting the new view controller without animation, and that's what I'm doing, but the problem persists.
I hope I've been clear enough on the issue, if you need more information just let me know.
EDIT: I'm presenting the login view controller on applicationDidBecomeActive: on applicationDelegate.m
In app delegate, In didFinishLaunchingWithOptions,
In condition if login or not,
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController =[storyboard instantiateViewControllerWithIdentifier:#"your identifier"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
You should something like this when you have view controller in storyboard.
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FirstViewController *firstviewController = [storyboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
SecondViewController *secondviewController = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
firstviewController.tabBarItem.image = [UIImage imageNamed:#"24-around-7"];
firstviewController.tabBarItem.title = #"First";
secondviewController.tabBarItem.title = #"Second";
secondviewController.tabBarItem.image = [UIImage imageNamed:#"60-around-7"];
UITabBarController *tabBarController = [[UITabBarController alloc]init];
tabBarController.viewControllers = #[firstviewController,secondviewController];
self.window.rootViewController = tabBarController;
And in FirstViewController's viewDidAppear you should check for user logged in or not and present view controller.
BOOL loginStatus = [[NSUserDefaults standardUserDefaults] boolForKey:#"isLoggedIn"];
if(loginStatus == NO){
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginViewController *loginViewcontroller = [storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
[self presentViewController:loginViewcontroller animated:YES completion:nil];
}
After successful login just dismiss login view controller . If user logout just present the loginviewcontroller
CREATE NEW .H .M
(this is my code)
yourController.h and yourController.m
then open
yourcontroller.m
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
NSLog(#"initWithFrame");
[self setupPinPopUp];
}
return self;
}
-(void)setupPinPopUp{
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
blurEffectView.frame = CGRectMake(0, 66, kSCREEN_WIDTH, kSCREEN_HEIGHT-66);
blurEffectView.userInteractionEnabled = TRUE;
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[blurEffectView addGestureRecognizer:singleFingerTap];
blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:blurEffectView];
UIView *popUpMainView = [[UIView alloc]initWithFrame:CGRectMake(kSCREEN_WIDTH/2-150, kSCREEN_HEIGHT/2-160, 300, 270)];
popUpMainView.backgroundColor = Clear;
[self addSubview:popUpMainView];
UIView *popUpInsideView = [[UIView alloc]initWithFrame:CGRectMake(kSCREEN_WIDTH/2-150, kSCREEN_HEIGHT/2-102, 300, 210)];
popUpInsideView.backgroundColor = White;
popUpInsideView.layer.cornerRadius = 2.0;
popUpInsideView.clipsToBounds = TRUE;
[self addSubview:popUpInsideView];
UIImageView *imgCircleView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 0, 100, 100)];
imgCircleView.layer.cornerRadius = 50;
imgCircleView.backgroundColor = White;
imgCircleView.clipsToBounds = TRUE;
[popUpMainView addSubview:imgCircleView];
UIImageView *imgInnerCircleView = [[UIImageView alloc]initWithFrame:CGRectMake(25, 8, 50, 50)];
imgInnerCircleView.backgroundColor = Clear;
imgInnerCircleView.image = [UIImage imageNamed:#"support"];
[imgCircleView addSubview:imgInnerCircleView];
UILabel *lblHeading = [[UILabel alloc]initWithFrame:CGRectMake(0, 20, popUpMainView.frame.size.width, 45)];
lblHeading.text = #"CUSTOMER SUPPORT";
lblHeading.numberOfLines = 0;
lblHeading.textColor = Black;
lblHeading.textAlignment = NSTextAlignmentCenter;
lblHeading.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:21];
[popUpInsideView addSubview:lblHeading];
UIButton *btnPhoneNumber = [[UIButton alloc]initWithFrame:CGRectMake(0, lblHeading.frame.size.height+lblHeading.frame.origin.y+10, popUpMainView.frame.size.width, 45)];
[btnPhoneNumber setTitle:#"18002345678" forState:UIControlStateNormal];
[btnPhoneNumber setTitleColor:Black forState:UIControlStateNormal];
btnPhoneNumber.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
btnPhoneNumber.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:18];
[btnPhoneNumber addTarget:self action:#selector(callSupport:) forControlEvents:UIControlEventTouchUpInside];
[popUpInsideView addSubview:btnPhoneNumber];
UIButton *btnEmail = [[UIButton alloc]initWithFrame:CGRectMake(0, btnPhoneNumber.frame.size.height+btnPhoneNumber.frame.origin.y+10, popUpMainView.frame.size.width, 45)];
[btnEmail setTitle:#"support#vurify.com" forState:UIControlStateNormal];
[btnEmail setTitleColor:Black forState:UIControlStateNormal];
btnEmail.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
btnEmail.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:18];
[btnEmail addTarget:self action:#selector(emailSupport:) forControlEvents:UIControlEventTouchUpInside];
[popUpInsideView addSubview:btnEmail];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
[self removeFromSuperview];
}
-(IBAction)callSupport:(id)sender{
NSString *phoneNumber = [#"tel://" stringByAppendingString:#"180023456789"];
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber] options:#{} completionHandler:^(BOOL success)
{
if (success) {
NSLog(#"Opened url");
}
}];
}
-(IBAction)emailSupport:(id)sender{
[self removeFromSuperview];
}
//call the method like this wherever you want to call
//IN APP DELEGATE
UIView *rectView;
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[rectView removeFromSuperview];
rectView = [[VurifyAppValidation alloc] initWithFrame:CGRectMake(0, 0, kSCREEN_WIDTH, kSCREEN_HEIGHT)];
[self.window addSubview:rectView];
}

RESideMenu: Add new viewcontrollers before RESideMenu

I am using RESideMenu in my application. But I need to add login and registration viewcontrollers before the RESideMenu.
Is it possible, if yes then how can I do that ?
Thanks in advance.
There are many ways to do this. The most common is you have a loginView controller and then in the app delegate you can write something like this in the app delegate:
if([[NSUserDefaults standardUserDefaults] valueForKey:#"AlreadyLogin"])
{
// So, here user already login then set your root view controller, let's say `SecondViewController``
SecondViewController *secondViewController = [storyBoard instantiateViewControllerWithIdentifier:#"SecondViewController"];
// then set your root view controller
self.window.rootViewController = secondViewController;
}
else
{
// It means you need to your root view controller is your login view controller, so let's create it
LoginViewController *loginViewController= [storyBoard instantiateViewControllerWithIdentifier:#"LoginViewController"];
self.window.rootViewController = loginViewController;
}
Credit: Skip view if user already logged
Yes it is very possible.
Solution A:
After successful login/sign up, do:
[UIApplication sharedApplication].window.rootViewController = [[RESideMenu alloc] init...];
Solution B:
Place your login/signup view controllers in the main content portion of the RESideMenu, and disable the two side menus until the user is signed in.
Solution C:
Embed the RESideMenu in a UINavigationController and optionally hide the navigation bar.
For more info I recommend researching "view controller containment" as that is the pattern used by RESideMenu, UINavigationController, and other types of "container" view controllers.
I hacked together a quick example of Solution C and it seems to work fine:
#implementation LoginViewController
- (void)viewDidLoad {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(50, 50, 100, 100);
[button setTitle:#"Login" forState:UIControlStateNormal];
[button addTarget:self action:#selector(goToRESideMenu) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
self.navigationController.navigationBarHidden = YES;
}
- (void)goToRESideMenu {
UIViewController *redViewController = [[UIViewController alloc] init];
redViewController.view.backgroundColor = [UIColor redColor];
UIViewController *greenViewController = [[UIViewController alloc] init];
greenViewController.view.backgroundColor = [UIColor greenColor];
UIViewController *blueViewController = [[UIViewController alloc] init];
blueViewController.view.backgroundColor = [UIColor blueColor];
RESideMenu *sideMenu = [[RESideMenu alloc] initWithContentViewController:redViewController
leftMenuViewController:greenViewController
rightMenuViewController:blueViewController];
[self.navigationController pushViewController:sideMenu animated:YES];
}
#end
The result looks like this:

modalPresentationStyle from button click

I have a _exampleButton:
_exampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_exampleButton setBackgroundColor:[UIColor redColor]];
[_exampleButton addTarget:self action:#selector(certificatesButtonTouched) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_exampleButton];
and the action:
-(void)certificatesButtonTouched
{
if(!_certificatesWindow)
{
_certificatesWindow = [[AWCertificatesViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
[_certificatesWindow release];
}
else {
[_certificatesWindow.view removeFromSuperview];
[_certificatesWindow release];
_certificatesWindow = nil;
}
}
this presents the window in modal view controller from other class:
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(cancel:)];
self.navigationItem.leftBarButtonItem = cancelItem;
UITableView *table = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
[self.view addSubview:table];
_tableFromButton = table;
}
- (void)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
but after clicking the Cancel button, the Modal view controller view disappears, but if I click the _exampleButton again once- it will not appear, so I have to click it twice to show the modal view controller again. What is the problem?
It does this because that is what your code tell it to do...
You dismiss the view controller in -(void)cancel:(id)sender but this will not result in the _certificatesWindow iVar becoming nil in your first view controller. So when you touch the exampleButton again it will execute the else clause and clean up the _certificatesWindow view controller.
You should either use delegation or a code block to have the first view controller dismiss the second or remove the if/else test from your certificatesButtonTouched. Another alternative is to modify this method so that if _certificatesWindow is not nil it is reused -
-(void)certificatesButtonTouched
{
if(!_certificatesWindow)
{
_certificatesWindow = [[AWCertificatesViewController alloc] init];
}
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
}
But this may or may not be desirable depending on what the second view controller shows.
I would also suggest you look at converting to ARC if possible
The problem is after you tap "Cancel", _certificatesWindow still exists when you tap on certificatesButtonTouched. It will go to the Else statement on the First tap to make _certificatesWindow = nil.
if _certificatesWindow is not needed when you tap cancel, you might want to do the following:-
- (void)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
[_certificatesWindow.view removeFromSuperview];
[_certificatesWindow release];
_certificatesWindow = nil;
}
allocate view like this in view did load method
if(!_certificatesWindow)
{
_certificatesWindow = [[ViewController1 alloc] init];
}
-(void)certificatesButtonTouched
{
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
}
replace your code with this
-(void)certificatesButtonTouched
{
if(!_certificatesWindow)
{
_certificatesWindow = [[AWCertificatesViewController alloc] init];
}
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
[_certificatesWindow release];
}

UINavigation bar back button not responding

I have a cameraview from which I'm pushing another view of with TableViewController. I can push the second view from my main view by using navbar controller. But the back button from the second view which is table view does not respond. I can't figure out why.
Thanks in advance.
#WrightCS Thank you for your immediate response.
In my app delegate.
ViewController *vc= [[ViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc];
[self.window setRootViewController :navController];
[self.window makeKeyAndVisible];
return YES;
Right now I'm using a temporary button to push the view.
-(IBAction)testButtonPressed {
TableView *tableVC = [[TableView alloc] initWithStyle:UITableViewStylePlain];
[self.navigationController pushViewController:tableVC animated:YES];
}
There are a few reasons your back button may not work:
You are using a custom UIButton and the frame/bounds are not correct you can use [yourButtonName sizeToFit]
to size it properly.
You are adding a button programmatically and not adding a click event:
[yourButtonName addTarget:self action:#selector(yourButtonNameTapped:) forControlEvents: UIControlEventTouchUpInside];
Don't forget your event.
...
-(void)yourButtonNamedTapped:(id)sender
{
...
}
docs: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIControl_Class/Reference/Reference.html
If you are using a UINavigationController, back will automatically show up when you use [self.navigationController pushViewController:viewControllerName];
-(IBAction)testButtonPressed {
TableView *tableVC = [[TableView alloc] initWithStyle:UITableViewStylePlain];
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[backBarButtonItem release];
[self.navigationController pushViewController:tableVC animated:YES];
}
I think it will be helpful to you.
- (void)viewDidLoad
{
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(backButtonDidClicked:)];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[backBarButtonItem release];
}
-(void)backButtonDidClicked :(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
It should work for you!!

Resources