How to pass value to another controller view in Xcode - cocoa

How do i get the value from different UIViewController in xcode storyBoard?

I end up using prepareForSegue method.
first i create a string in my third view controller.
#property (strong,nonatomic) NSString* stringFromSecondView;
Then I gave the push segue an ID called "getDate" and in my second view class use this code below and remember to import the thirdviewcontroller.h
#import "thirdViewController.h"
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"getDate"]){
NSString *intro = _myDate.text;
thirdViewController *vc = [segue destinationViewController];
vc.stringFromSecondView = intro;
}
}
Now back to my thirdViewController.m
_myLabel.text = stringFromSecondView;

In your second VIew Controller
- (IBAction) btnPressToBringThirdView : (id) sender
{
ThirdViewController* newObject = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
newObject.labelString = #"whatever text you want";
[self.navigationController pushViewController:newObject];
[newObject release];
}
In your third viewcontroller in .h file
#property (nonatomic, retain) NSString* labelString;
in .m file
- (void)viewDidLoad
{
[super viewDidLoad];
yourLabel.text = labelString;
}

ViewController *secondview=[[ViewController alloc]init];
secondview.your var here= secondview.your var here+100;//whate you var to change if NSintager
///to save your var
[[NSUserDefaults standardUserDefaults]setInteger:secondview.your var here forKey:#"your key to save"];

Related

How to import an UILabel from one UIViewcontroller to another

I've got a problem with xcode.
I'm a noob with object-c and xcode so... please help.
I have 2 Viewcontrollers: ViewController (with .m/.h) and HighScores (with .m/.h).
In HighScores I have put a label called first. And in ViewController I have a UITextField called *textField. I want the text in textField to be in the label when I enter the text AND when the score of the game already played is grater than the text already existing in the label ('first').
So,
This is how my HighScore.h looks like:
#import <UIKit/UIKit.h>
#interface HighScores: UIViewController {
IBOutlet UILabel *first;
}
#end
and this is ViewController.m:
#import "ViewController.h"
#import "HighScore.h"
...
NSString *myString = [HighScores.first];
if (score.text > myString) {
NSString *string = [textField text];
[HighScores.first setText:string]
but xcode says there's an error when I type "first" after the dot '.'... How can I make it if I want xCode to recognize the "first" label from HighScore UIViewController in VewController UiViewController?
Thanks!
In your code "first" is a UILabel , it will be generated when view of highScores get loaded .
Because it is a IBOUtlet.
Secondly you are trying yo access with class name .
Make a instance of HighScore class first and than try to acess label "first".
#import <UIKit/UIKit.h>
#interface HighScores: UIViewController
#property (nonatomic , strong)UILabel *firstLabel ;
#end
#implementation HighScores
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
{
self.firstLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 50)];
[self.view addSubview self.firstlabel];
}
#end
than in ViewController.m
HighScore * highscoreObject = [[HighScore alloc]init];
NSString *mystring = [highscoreObject.firstLabel text];
if (score.text > mystring) {
[highscoreObject.firstLabel setText:score.text];
{
Lets use notification , if you are confused in here:
In this case you can also use IBoutlet.
We will throw an notification with the string to be set and read the notification in HighScores and set the label with the string send.
In ViewController.m
if (score.text > myString) {
NSString *string = [textField text];
[[NSNotificationCenter defaultCenter] postNotificationName:#"update" object:string];
}
#interface HighScores: UIViewController
#property (nonatomic , strong) IBOutlet UILabel *firstLabel ;
#end
and in HighScores.m
#implementation HighScores
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(changetext:) name:#"update" object:nil];
}
- (void) changetext:(NSNotification *)notification {
NSLog(#"Received");
self.firstLabel.text = [notification object];
}

Page View Controller - from images to another view controller

I'm a bit perplexed about what I'm trying to accomplish. I have a page view controller that has a data source containing an array list of images. It's actually a tutorial that a user can flip through. What I'm trying to do is make the last page a log in screen so the user can enter info and hit a login button. I thought this would be as simple as adding a login view controller to the array but oooh how wrong I was D: When I tried that I got this error:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController _isResizable]: unrecognized selector sent to instance 0xa160660'
I do apologise for being such a noob I'm new to all of this just trying to get my head around it. Here's my code (accomplished by using this site actually):
My data source (ModelController.h)
#import <Foundation/Foundation.h>
#class DataViewController;
#interface ModelController : NSObject <UIPageViewControllerDataSource>
- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard;
- (NSUInteger)indexOfViewController:(DataViewController *)viewController;`
#end
ModelController.m
#import "ModelController.h"
#import "DataViewController.h"
#import "LoginViewController.h"
#interface ModelController()
#property (readonly, strong, nonatomic) NSArray *pageData;
#end
#implementation ModelController
- (id)init
{
self = [super init];
if (self)
{
// Create the data model
_pageData = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"tutorial1.png"],
[UIImage imageNamed:#"tutorial2.png"],
[UIImage imageNamed:#"lastWishes.png"],
[UIImage imageNamed:#"todo.png"],
[UIImage imageNamed:#"web.png"],
(LoginViewController*)[[UIViewController alloc] init],
nil];
}
return self;
}
- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard
{
// Return the data view controller for the given index.
if (([self.pageData count] == 0) || (index >= [self.pageData count]))
{
return nil;
}
// Create a new view controller and pass suitable data.
DataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:#"DataViewController"];
dataViewController.dataObject = self.pageData[index];
return dataViewController;
}
- (NSUInteger)indexOfViewController:(DataViewController *)viewController
{
// Return the index of the given data view controller.
// For simplicity, this implementation uses a static array of model objects and the view controller stores the model object; you can therefore use the model object to identify the index.
return [self.pageData indexOfObject:viewController.dataObject];
}
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(DataViewController *)viewController];
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index storyboard:viewController.storyboard];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(DataViewController *)viewController];
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageData count]) {
return nil;
}
return [self viewControllerAtIndex:index storyboard:viewController.storyboard];
}
#end
The Parent (RootViewController.h)
#import <UIKit/UIKit.h>
#interface RootViewController : UIViewController <UIPageViewControllerDelegate>
#property (strong, nonatomic) UIPageViewController *pageViewController;
#end
RootViewController.m
#import "RootViewController.h"
#import "ModelController.h"
#import "DataViewController.h"
#interface RootViewController ()
#property (readonly, strong, nonatomic) ModelController *modelController;
#end
#implementation RootViewController
#synthesize modelController = _modelController;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Configure the page view controller and add it as a child view controller.
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:nil];
self.pageViewController.delegate = self;
DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
self.pageViewController.dataSource = self.modelController;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
CGRect pageViewRect = self.view.bounds;
self.pageViewController.view.frame = pageViewRect;
[self.pageViewController didMoveToParentViewController:self];
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (ModelController *)modelController
{
// Return the model controller object, creating it if necessary.
// In more complex implementations, the model controller may be passed to the view controller.
if (!_modelController) {
_modelController = [[ModelController alloc] init];
}
return _modelController;
}
#pragma mark - UIPageViewController delegate methods
/*
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating: (BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted: (BOOL)completed
{
}
*/
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
// Set the spine position to "min" and the page view controller's view controllers array to contain just one view controller. Setting the spine position to 'UIPageViewControllerSpineLocationMid' in landscape orientation sets the doubleSided property to YES, so set it to NO here.
UIViewController *currentViewController = self.pageViewController.viewControllers[0];
NSArray *viewControllers = #[currentViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
self.pageViewController.doubleSided = NO;
return UIPageViewControllerSpineLocationMin;
}
#end
The Child (DataViewController.h)
#import <UIKit/UIKit.h>
#interface DataViewController : UIViewController
#property (strong, nonatomic) id dataObject;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#end
DataViewController.m
#import "DataViewController.h"
#interface DataViewController ()
#end
#implementation DataViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.imageView.image = _dataObject;
}
#end
Once again, the code in question is here where I'm trying to add a view controller to the data source as the last page:
_pageData = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"tutorial1.png"],
[UIImage imageNamed:#"tutorial2.png"],
[UIImage imageNamed:#"lastWishes.png"],
[UIImage imageNamed:#"todo.png"],
[UIImage imageNamed:#"web.png"],
(LoginViewController*)[[UIViewController alloc] init],
nil];
and getting unrecognized selector error when at runtime. I've also tried this as well:
- (id)init
{
self = [super init];
if (self)
{
LoginViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
// Create the data model
_pageData = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"tutorial1.png"],
[UIImage imageNamed:#"tutorial2.png"],
[UIImage imageNamed:#"lastWishes.png"],
[UIImage imageNamed:#"todo.png"],
[UIImage imageNamed:#"web.png"],
viewController,
nil];
}
return self;
}
Any suggestions would be great. THanks!!
Your idea is 100% correct, your implementation is not.
This line:
dataViewController.dataObject = self.pageData[index];
is very suspicious because that will return a UIViewController in the case of your login screen. I would suggest you type-check your page data, if it is already a UIViewController subclass, just return it, if it is (in your case) a UIImage add it as the data object.

xCode: Activating an IBAction from within a dynamically added subview

I have a separate UIView class that constructs a simple footer bar that contains a UIButton.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:CGRectMake(0, 410, 320, 50)];
if (self) {
int buttonHeight = self.frame.size.height;
int buttonWidth = 70;
int nextBtnPosX =0;
int nextBtnPosY =0;
self.backgroundColor =[UIColor colorWithRed:254.0/255.0 green:193.0/255.0 blue:32.0/255.0 alpha:1.0];
[self sendSubviewToBack:self];
UIButton *nextBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[nextBtn setTitle:#"Next" forState:UIControlStateNormal];
nextBtn.frame = CGRectMake(nextBtnPosX, nextBtnPosY, buttonWidth, buttonHeight);
[nextBtn addTarget:self.superview action:#selector(GoToNextPage) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:nextBtn];
}
return self;
}
I have several ViewControllers that then add this footer view class above to each view as a subview.
UIView *newFooter = [[theFooter alloc] init];
[self.view addSubview:newFooter];
Now the actual UIButton within the footer view needs to have its taget different for each viewController it is added to.
So I though it would be best to add the IBAction to the actual view controller then call this via the footer view.
But this is where I have come into a problem. How do I call the parent Controller to init the IBAction(GoToNextPage) from within the footer subview, from the addTarget?
Also would it be easier to have it all within the footer subview and pass in the target required, if so how else would this be done.
Here is a rough overview on what you should do.
This is how your UIView's header file should look
#protocol myViewControllerDelegate <NSObject>
#optional
- (void)didPushButton:(id)sender;
#end
#interface UIViewController : UITableViewController
{
__unsafe_unretained id <myViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <myViewControllerDelegate> delegate;
#end
Remember to #synthesize delegate; in your main file.
Finally in your main file, you will have an IBAction that receives the UIButton action.
Let's say that action is named buttonPushed.
Set that action to:
- (IBAction)buttonPushed:(id)sender
{
if (delegate)
[delegate didPushButton:sender];
}
Finally remember, that you need to set the delegate to each viewController you are using this viewController.
UIView *newFooter = [[theFooter alloc] init];
[self.view addSubview:newFooter];
newFooter.delegate = self;

how to set the property of the ViewController before presenting it as presentModalViewController?

I present the view controller like this:
FBViewController *fbViewController =[[FBViewController alloc] initWithNibName:#"FBViewController" bundle:nil];
fbViewController.label.text=#"hello"; // I set the value of the property label which is the outlet
[self presentModalViewController:fbViewController animated:YES];
FBViewController.h:
#import <UIKit/UIKit.h>
#interface FBViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *label;
#end
FBViewController.m:
...
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"%#", self.label.text); // Here instead of "hello" i get the value which was in nib file.
}
...
The question is how to set the value of the label?
You can pass the NSString retrieve text to assign label modalview controller:
FBViewController *fbViewController =[[FBViewController alloc] initWithNibName:#"FBViewController" bundle:nil];
fbViewController.labeltext=#"Your Text";
[self presentModalViewController:fbViewController animated:YES];
FBViewController.h
#interface FBViewController : UIViewController {
NSString *labeltext;
}
#property (nonatomic, retain) NSString *labeltext;
and use view to load method in FBViewController.m
- (void)viewDidLoad {
label1.text=labeltext;
}

Multiple Views for UITabBarController

I'm trying to build an app where I have a TabBarController with 4 entries.
When I select the first entry, a view with a UITableView shows up.
This TableView is filled with several entries.
What I would like to do is:
When an entry out of that UITableView gets selected, another view should show up; a detailview.
.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
if(self.secondView == nil) {
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondView" bundle:[NSBundle mainBundle]];
self.secondView = secondViewController;
[secondViewController release];
}
// Setup the animation
[self.navigationController pushViewController:self.secondView animated:YES];
}
}
.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController {
SecondViewController *secondView;
NSMutableArray *myData;
}
#property (nonatomic, retain) SecondViewController *secondView;
#property (nonatomic, copy, readwrite) NSMutableArray* myData;
#end
This is what I have so far.
Unfortunately.. the code runs, bit the second view does not show up.
Is your first view controller wrapped in a UINavigationController? When you set up your UITabBarController, you should add UINavigationControllers rather than your UIViewController subclasses, e.g.:
FirstViewController *viewControl1 = [[FirstViewController alloc] init];
UINavigationController *navControl1 = [[UINavigationController alloc] initWithRootViewController:viewControl1];
UITabBarController *tabControl = [[UITabBarController alloc] init];
tabControl.viewControllers = [NSArray arrayWithObjects:navControl1, <etc>, nil];
//release everything except tabControl
Also, based on your code, you don't need to keep your secondViewController as an ivar, since UINavigationController automatically retains its view controllers (and retaining it when you're not displaying it will use up unnecessary memory).

Resources