I have label in my secondviewcontroller. I would like to pass button index from firstviewcontroller to secondviewcontroller label. When I press button, it goes to second viewcontroller but label is nil
// FirstViewController.m
NSInteger index = [carousel indexOfItemViewOrSubview:sender];
int ind=index;
SecondViewController *sVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:[NSBundle mainBundle]];
sVC.myLabel.text=[NSString stringWithFormat:#"%d",ind];
[self presentModalViewController:sVC animated:YES];
//SecondViewController.h
#property (strong, nonatomic) IBOutlet UILabel *myLabel;
//SecondViewController.m
#synthesize myLabel;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(#"%#",myLabel.text);
}
In the SecondViewController.h add another property:
#property (nonatomic) NSInteger index;
Then in the FirstViewController.m pass the value of index to the index of the second view:
NSInteger index = [carousel indexOfItemViewOrSubview:sender];
int ind=index; //now you don't need this
SecondViewController *sVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:[NSBundle mainBundle]];
sVC.myLabel.text=[NSString stringWithFormat:#"%d",ind];
// New line
sVC.index = index;
[self presentModalViewController:sVC animated:YES];
Related
I'm currently working with multi-storyboard project, and I'm make an custom UIView inside an UIViewController (I named it "Tab Bar VC") and make it look like a tab bar with the tutorial from this link:
https://github.com/codepath/ios_guides/wiki/Creating-a-Custom-Tab-Bar
Everything show up normally but the problem is when I press on tab bar items the navigation bar doesn't show and I can't push to another view controller without it. I have tried to embed my "Tab Bar VC" in navigation controller like this picture but it's doesn't work:
Note that in my case I don't wanna use UITabBarViewController or Storyboard Reference. Please help me.
Thank in advance.
Here is my code of Tab Bar VC:
#import "SHTabViewController.h"
#import "SHHomeViewController.h"
#import "SHTicketViewController.h"
#import "SHNotificationViewController.h"
#import "SHChatViewController.h"
#import "SHCallViewController.h"
#interface SHTabViewController () {
NSMutableArray *viewcontrollers;
NSInteger selectedIndex;
}
#property (weak, nonatomic) IBOutlet UIView *contentView;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *tabButtons;
#property (strong, nonatomic) SHHomeViewController *homeVC;
#property (strong, nonatomic) SHCallViewController *callVC;
#property (strong, nonatomic) SHChatViewController *chatVC;
#property (strong, nonatomic) SHTicketViewController *ticketVC;
#property (strong, nonatomic) SHNotificationViewController *notifVC;
#end
#implementation SHTabViewController
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
selectedIndex = 0;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
selectedIndex = 0;
UIStoryboard *homeStoryboard = [UIStoryboard storyboardWithName:#"Home" bundle:[NSBundle mainBundle]];
UIStoryboard *callStoryboard = [UIStoryboard storyboardWithName:#"CallPM" bundle:[NSBundle mainBundle]];
UIStoryboard *chatStoryboard = [UIStoryboard storyboardWithName:#"Chat" bundle:[NSBundle mainBundle]];
UIStoryboard *ticketStoryboard = [UIStoryboard storyboardWithName:#"Ticket" bundle:[NSBundle mainBundle]];
UIStoryboard *notifStoryboard = [UIStoryboard storyboardWithName:#"Notification" bundle:[NSBundle mainBundle]];
self.homeVC = [homeStoryboard instantiateViewControllerWithIdentifier:#"homeVC"];
self.callVC = [callStoryboard instantiateViewControllerWithIdentifier:#"callVC"];
self.chatVC = [chatStoryboard instantiateViewControllerWithIdentifier:#"chatVC"];
self.ticketVC = [ticketStoryboard instantiateViewControllerWithIdentifier:#"ticketVC"];
self.notifVC = [notifStoryboard instantiateViewControllerWithIdentifier:#"notificationVC"];
viewcontrollers = [NSMutableArray new];
[viewcontrollers addObject:self.homeVC];
[viewcontrollers addObject:self.callVC];
[viewcontrollers addObject:self.chatVC];
[viewcontrollers addObject:self.ticketVC];
[viewcontrollers addObject:self.notifVC];
[self.tabButtons[selectedIndex] setSelected:YES];
[self didPressTab:self.tabButtons[selectedIndex]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)didPressTab:(UIButton *)sender {
selectedIndex = 0;
sender.selected = YES;
NSInteger previousIndex = selectedIndex;
selectedIndex = sender.tag;
[self.tabButtons[previousIndex] setSelected:NO];
UIViewController *previousVC = viewcontrollers[previousIndex];
[previousVC willMoveToParentViewController:nil];
[previousVC.view removeFromSuperview];
[previousVC removeFromParentViewController];
UIViewController *vc = viewcontrollers[selectedIndex];
[self addChildViewController:vc];
vc.view.frame = self.contentView.bounds;
[self.contentView addSubview:vc.view];
[vc didMoveToParentViewController:self];
}
Don't embed 'Tab bar VC' with UINavigationViewController. Embed UINavigationViewController with each of a individual UIViewControllers you added in 'Tab bar VC'.
You should embed all individual view controllers with a navigation controller.
TabBarController > NavigationController > Viewcontroller
For this you need to add a NavigationController for every Controllers like below
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
selectedIndex = 0;
UIStoryboard *homeStoryboard = [UIStoryboard storyboardWithName:#"Home" bundle:[NSBundle mainBundle]];
UIStoryboard *callStoryboard = [UIStoryboard storyboardWithName:#"CallPM" bundle:[NSBundle mainBundle]];
UIStoryboard *chatStoryboard = [UIStoryboard storyboardWithName:#"Chat" bundle:[NSBundle mainBundle]];
UIStoryboard *ticketStoryboard = [UIStoryboard storyboardWithName:#"Ticket" bundle:[NSBundle mainBundle]];
UIStoryboard *notifStoryboard = [UIStoryboard storyboardWithName:#"Notification" bundle:[NSBundle mainBundle]];
self.homeVC = [homeStoryboard instantiateViewControllerWithIdentifier:#"homeVC"];
self.callVC = [callStoryboard instantiateViewControllerWithIdentifier:#"callVC"];
self.chatVC = [chatStoryboard instantiateViewControllerWithIdentifier:#"chatVC"];
self.ticketVC = [ticketStoryboard instantiateViewControllerWithIdentifier:#"ticketVC"];
self.notifVC = [notifStoryboard instantiateViewControllerWithIdentifier:#"notificationVC"];
UINavigationController *homeNavController = [[UINavigationController alloc] initWithRootViewController: self.homeVC];
UINavigationController *callVCNavController = [[UINavigationController alloc] initWithRootViewController: self.callVC];
UINavigationController *chatVCNavController = [[UINavigationController alloc] initWithRootViewController: self.chatVC];
UINavigationController *ticketVCNavController = [[UINavigationController alloc] initWithRootViewController: self.ticketVC];
UINavigationController *notifVCNavController = [[UINavigationController alloc] initWithRootViewController: self.notifVC];
viewcontrollers = [NSMutableArray new];
[viewcontrollers addObject: homeNavController];
[viewcontrollers addObject: callVCNavController];
[viewcontrollers addObject:ticketVCNavController];
[viewcontrollers addObject:chatVCNavController];
[viewcontrollers addObject: notifVCNavController];
[self.tabButtons[selectedIndex] setSelected:YES];
[self didPressTab:self.tabButtons[selectedIndex]];
You are using wrong approach. You are embedding tab bar controller in a navigation controller which logically doesn't make any sense.Instead you should embed various navigation controllers into one tab bar controller. Try doing something like this:
I have a UILabel in interface builder that I've connected to a property, but it's staying nil through the viewDidLoad on that view controller. I've been stepping through and as soon as the DetailViewController is initialized, the label property is there but it is nil and it never seems to be initialized.
It was working until I switched from using segues to doing pushViewController on the navigation controller.
// DetailsViewController.h
#import <UIKit/UIKit.h>
#import "TLitem.h"
#interface DetailsViewController : UIViewController
#property (nonatomic, strong) TLitem *entry;
#property (weak, nonatomic) IBOutlet UILabel *entryLabel;
#end
Then in a table view in another view controller:
// EntryListViewController.m
DetailsViewController *details = [[DetailsViewController alloc] init];
[details setEntry:entry];
[self.navigationController pushViewController:details animated:YES];
And in the viewDidLoad:
// DetailsViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor yellowColor]];
TLitem *entry = [self entry];
UILabel *label = [self entryLabel];
label.text = [entry valueForKey:#"text"];
[[DetailsViewController alloc] init] is not loading the view controller from the storyboard. It creates a new DetailsViewController, but nothing from IB will be connected. Look into -instantiateViewControllerWithIdentifier:
It will look something like
DetailsViewController *details = [self.storyboard instantiateViewControllerWithIdentifier:#"Some Storyboard Identifier You Create"];
details.entry = entry;
[self.navigationController pushViewController:details animated:YES];
I have a view controller which is my HomeViewController, and I have a modal segue between them.
This is the HomeViewController:
import "HomePageViewController.h"
#import "CreatePageViewController.h"
#import "StackTableViewController.h"
#import "PopUpView.h"
#interface HomePageViewController ()
#property (nonatomic, strong) IBOutlet UIButton *toggleButton;
#property (nonatomic, strong) CreatePageViewController *modalTest;
#property (nonatomic, strong) PopUpView *popup;
#end
#implementation HomePageViewController
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
-(void)viewDidLoad {
[super viewDidLoad];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:Nil];
_modalTest = [storyboard instantiateViewControllerWithIdentifier:#"ModalTest"];
[_toggleButton addTarget:self action:#selector(go) forControlEvents:UIControlEventTouchUpInside];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(hide) name:#"HideAFPopup" object:nil];
}
-(void)go {
_popup = [PopUpView popupWithView:_modalTest.view];
[_popup show];
}
-(void)hide {
[_popup hide];
}
- (IBAction)pushToNextViewController:(id)sender {
StackTableViewController *vc = [[StackTableViewController alloc]init];
[self presentModalViewController:vc animated:YES];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
I want to add a navigation controller to StackTableViewController...its just a table view and I want it to have a navigation controller, how should I do this?
Also, why xcode tells me my modal method presentModalViewController is deprecated?
tnx
Create a new instance of UINavigationController, with your StackTableViewController as its rootViewController. Then present the navigation controller:
- (IBAction)pushToNextViewController:(id)sender {
StackTableViewController *vc = [[StackTableViewController alloc]init];
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:navCtrl animated:YES completion:nil];
}
Note that presentModalViewController:animated: is deprecated because it has been replaced by presentViewController:animated:completion:.
I have a Add View where when you tap on Category, the following code is executed
- (void)categoryTapped {
CategoryGroupViewController *categoryGroupViewController = [[CategoryGroupViewController alloc] initWithNibName:#"CategoryGroupViewController" bundle:nil];
[self presentViewController:categoryGroupViewController animated:YES completion:nil];
}
CategoryGroupViewController.h looks like
#interface CategoryGroupViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UINavigationController *navigationController;
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#end
CategoryGroupViewController.m looks like
#import "CategoryGroupViewController.h"
#import "Helper.h"
static NSString *CellIdentifier = #"Cell";
#interface CategoryGroupViewController ()
#property(nonatomic, strong) NSArray *categories;
#end
#implementation CategoryGroupViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// (todo) should come from API
self.categories = #[#"Food & Drink", #"Utilities"];
}
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(#"categoryGroup View loaded");
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self];
self.navigationController.title = #"Pick Category";
}
...
}
When I run my application, I see the following in log
2014-11-20 21:29:53.589 myapp-ios[30332:70b] categoryGroup View loaded
But on Simulator, I see
Why don't I see NavigationController?
As you are presenting your CategoryGroupViewController it will not show Navigation Bar by default.
You have to set your CategoryGroupViewController as rootViewController for UINavigationController and instead of presenting CategoryGroupViewController present newly created UINavigationController.
- (void)categoryTapped{
CategoryGroupViewController *categoryGroupVC = [[CategoryGroupViewController alloc] initWithNibName:#"CategoryGroupViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController: categoryGroupVC];
[self presentViewController:categoryGroupViewController animated:YES completion:nil];
}
as i mentioned above if u want a navigaioncontroller u can set CategoryGroupViewController as a root view for a navigation controller and present it for example,
- (void)categoryTapped
{
CategoryGroupViewController *categoryGroupViewController = [[CategoryGroupViewController alloc] initWithNibName:#"CategoryGroupViewController" bundle:nil];
//add this
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController: categoryGroupViewController];
//present the navigation controller which contains root view controller categoryGroupViewController
[self presentViewController:navController animated:YES completion:nil];
}
You need to instantiate a rootViewController before View did load
[alink]https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
UIViewController already as a navigationController property, so this is redundant:
// Remove this property from CategoryGroupViewController
#property (nonatomic, strong) UINavigationController *navigationController;
Structuring the user interface in the way you are attempting is also incorrect, and would result in a circular reference between CategoryGroupViewController and UINavigationController. First you need to modify your -viewDidLoad method like so:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(#"categoryGroup View loaded");
// UINavigationController will use this automatically.
self.title = #"Pick Category";
}
Then you should change the way you go about preseting the view controller in your original method:
- (void)categoryTapped {
CategoryGroupViewController *categoryGroupViewController = [[CategoryGroupViewController alloc] initWithNibName:#"CategoryGroupViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:categoryGroupViewController];
[self presentViewController:navController animated:YES completion:nil];
}
Finally, the introduction in the UINavigationController documentation has a great explanation of how the class should be used. Taking a few minutes to read it would help you tremendously in the future.
I've followed several guides on passing data between view controllers, but they seem to involve setting the secondViewController's property in any equivalent of a -(void)goToNextView method. I'm trying to figure out how to assign a value to a property in a 2nd view controller from the first while using a tab bar controller created in the app delegate.
Current setup:
AppDelegate.m
#synthesize window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
...
UITabBarController *tbc = [[UITabBarController alloc] init];
FirstViewController *vc1 = [[FirstViewController alloc] init];
SecondViewController *vc2 = [[SecondViewController alloc] init];
[tbc setViewControllers: [NSArray arrayWithObjects: vc1, vc2, nil]];
[[self window] setRootViewController:tbc];
[self.window makeKeyAndVisible];
return YES;
}
...
#end
FirstViewController.h
#import "SecondViewController.h"
#interface FirstViewController : UIViewController
{
SecondViewController *vc2;
IBOutlet UISlider *sizeSlider;
}
#property (nonatomic, retain) SecondViewController *vc2;
#property (strong, nonatomic) UISlider *mySlider;
-(IBAction) mySliderAction:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation FirstViewController
#synthesize vc2, mySlider;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:#"xib"];
}
return self;
}
...
- (IBAction) mySliderAction:(id)sender
{
NSString *str = [[NSString alloc] initWithFormat:#"%3.2f", mySlider.value];
if(self.vc2 == nil)
{
SecondViewController *viewTwo = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
self.vc2 = viewTwo;
}
vc2.sliderValueString = str;
}
...
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#import "myView.h"
#interface SecondViewController : UIViewController
{
NSString *sliderValueString;
}
#property (copy) NSString *sliderValueString;
#end
SecondViewController.m
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize sliderValueString;
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
self = [super initWithNibName:nil bundle:nil];
if (self) {
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:#"View 2"];
}
return self;
}
-(void) loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
myView *view = [[myView alloc] initWithFrame:frame];
printf("Slider Value: %s", [sliderValueString UTF8String]);
[self setView: view];
}
...
#end
myView.h and .m are likely irrelevant to the question, but I've got the .h subclassing UIView, and the .m creating the view with -(id)initWithFrame:(CGRect)frame
I'm guessing that I'm assigning the 2nd VC's property in the wrong place (mySliderAction), given that the printf() in the 2nd VC is blank, so my question is: Where should the property be assigned, or what am I doing wrong that is preventing the 2nd VC from allowing it's sliderValueString to not be (or remain) assigned?
Thanks!
You are fine setting the property in mySliderAction, the trouble is that you are setting it on the wrong object.
In the App Delegate you create a viewController for tabControllers' item 2:
SecondViewController *vc2 = [[SecondViewController alloc] init];
In vc1's mySliderAction you also create an instance of vc2:
SecondViewController *viewTwo = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
This is not the instance that you navigate to via the second tab on the tabController, but it is the one who's sliderValueString property you are setting.
Instead of making a new instance here, you need to refer to the already-existing instance:
SecondViewController *viewTwo = [self.tabBarController.viewControllers objectAtIndex:1]
Then you should be ok.