I have a program with multiple views, one of them has labels (LabelView for this question), the other has text fields(TextView for this question). I would like to take the info from the text fields, and put it on the label, I think the easiest way to do this by calling a method LabelView from TextView.
I have tried a couple things:
I tried putting a method in LabelView that changed the label's values with parameters. Then calling the method in TextView and passing the data through the parameters.
I tried making a delegate, using this question. Unfortunately the last step (add settingView.viewControllerDelegate=self to the viewDidLoad method) failed. settingView was an undeclared identifier.
Does anyone know what I should do?
EDIT: Here is some I have done, using Xman's Parent/Child view idea. This is in TextView.m:
NSInteger curScore = [self.ToP1Score.text integerValue];
NSInteger curPhase = [self.ToP1Phase.text integerValue];
self.ToP1Score.text = [NSString stringWithFormat:#"%d", (curScore += [self.player1Txt.text integerValue])];
if ([self.player1Txt.text integerValue] < 50) {
self.ToP1Phase.text = [NSString stringWithFormat:#"%d", (curPhase += 1)];
}
Two ways to achieve this.
1) Make ChildView as a childView of ParentView so that you can directly access ParentView properties in ChildView as following
ParentView.h
#interface ParentView : UIView
#property (nonatomic,strong) UITextField *mytextField;
#end
ChildView.h
#import "ParentView.h"
#interface ChildView : ParentView
#property (nonatomic,strong) UILabel *myLabel;
#end
2) Use Notification
Put this in FirstView where the textField is :
[[NSNotificationCenter defaultCenter] postNotificationName:#"sendData" object:yourTextFiels userInfo:nil];
Put this in SecondView where your Label is.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(changeLabelValue:) name:#"sendData" object:nil];
and also this method
-(void)changeLabelValue(NSNotification *)iRecognizer {
UITextField *myTextField = iRecognizer object];
//Here You can change the value of label
}
Hope this will help you.
suppose you are passing some text from firststViewController to secondViewController,
then in firststviewcontroller add these lines of code
-(IBAction)goToNextScreen:(id)sender
{
secondViewController *newVc = [[secondViewController alloc]initWithNibName:#"secondViewController" bundle:nil];
// or if you are using storyboard
// NewViewController *newVc = [self.storyboard instantiateViewControllerWithIdentifier:#"identifier"];
newVc.text = #" Your text ";
[self.navigationController pushViewController:newVc animated:YES];
}
in 2ndViewController.h file
#import <UIKit/UIKit.h>
#interface secondViewController : UIViewController
{
NSString text;
}
#property(nonatomic, retain)NSString text;
#property (weak, nonatomic) IBOutlet UILabel *lbl;
#end
in .m file
#import "secondViewController.h"
#interface secondViewController ()
#end
#implementation secondViewController
#synthesize text,lbl;
- (void)viewDidLoad
{
lbl.text = text;
}
#end
hope this will help you.. Dont forget to up vote...
Related
the purpose: write some html code in viewcontroller1's text field press button, the result is shown in webview in viewcontroller2
This is what i've written so far
#import <UIKit/UIkit.h>
#import <Foundation/Foundation.h>
#interface vc1 : UIViewController
#property (weak, nonatomic) IBOutlet UIButton * btn;
#property (weak, nonatomic) IBOutlet UITextField * tf;
the text field can be just a standard one, all i need to do is make sure
that when the user hits the button the vc2 comes up and in it's HTML section
is a string that i got from the textfield
the method responsible for this action is mentioned below
-(IBAction) btnAction : (id) sender;
#end
#interface vc2 : UIViewController
#property (weak, nonatomic) IBOutlet UIWebView * wv;
#end
//didn't find standard implementation for vc1
//attempted implementation for vc1
#implementation vc1
#synthesize btn, tf;
-(id) initWithNibName: (NSString *)nibName0rNil bundle: (NSBundle *)nibBundle0rNil{
self = [super initWithNibName: nibName0rNil bundle: nibBundle0rNil];
if(self){
//custom init
}
return self;
}
-(IBAction) btnAction : (id) sender {
//initialize vc2? it's a class so i can't call it.
//can i save the contents of the object as a NSString? or can i just give the Webview a textfield object to show as HTML?
}
#end
#implementation vc2
#synthesize wv;
-(id) initWithNibName: (NSString *)nibName0rNil bundle: (NSBundle *)nibBundle0rNil{
self = [super initWithNibName: nibName0rNil bundle: nibBundle0rNil];
if(self){
//custom init
}
return self;
}
-(void)viewDidLoad{
[super viewDidLoad];
this is where i am supposed to tell it to take the text from vc1 and display it as HTML
[wv loadHTMLString:#"<html><body>YOUR-TEXT-HERE</body></html>" baseURL:nil]
something of the sort but the string is replaced with what was inserted into vc1's text field
}
-(void)viewDidUnload{
[self setWebview: nil];
[super viewDidUnload];
}
-(BOOL)shouldAutorotateToTinterfaceOrientation:(UIInterfaceOrientation)interfaveOrientation{
return interfaceOrientation == UIInterfaceOrientationPortrait;
}
#end
Edit: thank you for posting, this community has been very helpful.
In Interface of vc2.h declare a property like
#property (strong, nonatomic) NSString *htmlString;
In vc1.h file or vc1.h add
#import "vc2.h"
Now in the Button Action Use the following code:
-(IBAction) btnAction : (id) sender {
//initialize vc2? it's a class so i can't call it.
//can i save the contents of the object as a NSString? or can i just give the Webview a textfield object to show as HTML?
//With Xib
vc2 *secondVC =[[vc2 alloc]initWithNibName:#"vc2" bundle:nil];
secondVC.htmlString = self.tf.text;//textField property name
[self.navigationController pushViewController:secondVC animated:YES];
}
Finally to display the WebView in vc1.m use :
NSString *myHTMLString = [[NSString alloc] initWithFormat:#"%#", self.htmlString];
[self.wv loadHTMLString:myHTMLString baseURL:nil];
Hope this helps. Please let me know in case of any specific errors.
In Swift
let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
secondViewController.myStringValue = myTextField.text
self.navigationController?.pushViewController(secondViewController, animated: true)
Load the webview in the secondViewController's viewDidload method
I have two storyboards and each one has its own respective view controller but I need to change the appearance of the second storyboard based on the button pressed in the first view controller.
In the first view controller I have:
// First view controller .h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *LevelOneButton; // tag 0
#property (strong, nonatomic) IBOutlet UIButton *LevelTwoButton; // tag 1
-(IBAction)selectLevel:(UIButton *)sender; // both buttons connected to this method
#property (assign, nonatomic) int levelSelect;
#end
then in the first .m file:
//FirstViewController.m
-(IBAction)selectLevel:(UIButton *)sender {
if (sender.tag == 0) {
_levelSelect = 0;
}
if (sender.tag == 1) {
_levelSelect = 1;
}
}
This code works fine but the problem occurs in the secondViewController that I have. When I try and access the levelSelect property in the SecondViewController I get the errors "Property 'levelSelect' not found on object of type 'FirstViewController'" or "Unexpected identifier levelSelect" or something among those lines. I've tried every single thing I could think of and every question I found on StackOverflow relating to this but none have fixed the problem. Anyone know what I'm doing wrong?
You should be setting the property on the second view controller as you're pushing or segueing.
So in your first view controller it should look something like this:
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIButton *levelOne;
#property (strong, nonatomic) IBOutlet UIButton *levelTwo;
#property (assign, nonatomic) int selectedLevel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.levelOne.tag = 1;
self.levelTwo.tag = 2;
}
- (IBAction)selectLevel:(UIButton *)sender
{
if (sender.tag == 1) {
self.selectedLevel = 1;
} else {
self.selectedLevel = 2;
}
[self performSegueWithIdentifier:#"pushToSecond" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SecondViewController *dest = segue.destinationViewController;
dest.levelSelect = self.selectedLevel;
}
#end
Now, when viewDidLoad gets called on the SecondViewController that property will be set and you can use it. Like so:
#import "SecondViewController.h"
#interface SecondViewController ()
#property (strong, nonatomic) IBOutlet UILabel *levelLabel;
#end
#implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.levelLabel.text = [#(self.levelSelect) stringValue];
}
#end
Quick Edit, if you're not using segues you can do the same thing by pushing manually. Would look something like:
- (IBAction)selectLevel:(UIButton *)sender
{
if (sender.tag == 1) {
self.selectedLevel = 1;
} else {
self.selectedLevel = 2;
}
SecondViewController *secondVC = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"second"];
secondVC.levelSelect = self.selectedLevel;
[self.navigationController pushViewController:secondVC animated:YES];
}
I'm using a Split View Controller for an iPad app. I'm trying to send a label change to the detailReceiving Controller from the rootSending Controll when a button is pushed. I've read through tutorials on protocols and came up with the code below. When I click the button on rootSending, nothing happens to the label on detailReceiving. Do I have to do something else with a splitViewContoller so that the label will update? Shouldn't detailReceiving change the label when it receives the message?
rootSending.h
#import <UIKit/UIKit.h>
#protocol TestDelegate <NSObject>
-(void)tester:(NSString*)testString;
#end
#interface rootSending : UIViewController
#property (nonatomic, assign) id <TestDelegate> delegate;
#end
rootSending.m
#import "rootSending.h"
#implementation rootSending
#synthesize delegate;
-(void)viewDidLoad{
}
-(IBAction)buttonPressed:(id)sender{
[delegate tester:#"button pressed"];
}
#end
detailReceiving.m
#import "detailReceiving.h"
#import "rootSending.h"
#interface detailReceiving ()<TestDelegate>{
IBOutlet UILabel *label2;
}
#end
#implementation detailReceiving
-(void)viewDidLoad{
rootSending *obj = [rootSending alloc];
obj.delegate = self ;
}
-(void)tester:(NSString *)testString{
label2.text = testString;
}
#end
First of all, never ever have an alloc without an init! But in this case, even if you did use alloc/init, it still wouldn't work because that just creates a new instance of rootSending, not the one that you have in your split view. You need to get a reference to the one you have, which you can get from the split view controller,
-(void)viewDidLoad{
rootSending *obj = (rootSending *)self.splitViewController.viewControllers.firstObject;
obj.delegate = self;
}
After Edit:
If your mate controller is embedded in a navigation controller, then you need to get the navigation controller's topViewController to get your reference.
-(void)viewDidLoad{
UINavigationController *nav = (UINavigationController *)self.splitViewController.viewControllers.firstObject;
xmlListOfItems *obj = (xmlListOfItems *)nav.topViewController;
obj.delegate = self;
}
Im building an app that calls different subviews and lay them over in a main view controller (http://imgur.com/p6l9Oac)
when ever the user clicks a button on the bottom part of the screen (lets call it sliding menu!) the view behind it will disappear and new one will show up.
one of the subviews is Settings , which it have some switches to enable/disable some of the buttons.
in the SettingsViewController.
Ive set a protocol:
#protocol SettingsViewControllerDelegate <NSObject>
#required
-(void)hideCountdownView;
-(void)showCountdownView;
#end
and the interface contains:
#interface SettingsHubViewController : UIViewController
#property (weak, nonatomic) IBOutlet UISwitch *enableCountdown;
#property (nonatomic, assign) id <SettingsViewControllerDelegate> delegate;
#property (weak, nonatomic) IBOutlet UIView *mainView;
#end
and in the Implementation:
- (IBAction)switchAction:(id)sender {
if (!self.enableCountdown.on) {
NSLog(#"The view is Hidden");
[_delegate hideCountdownView];
} else if (self.enableCountdown.on) {
NSLog(#"The view is Shown");
[_delegate showCountdownView];
}
}
You can see i used _delegate to use the show and hide functions, I used NSLog to make sure that Im calling the functions correctly.
in the MainViewController
#import "SettingsHubViewController.h"
#interface MainViewController () <SettingsViewControllerDelegate>
#property (nonatomic, strong) SettingsHubViewController * settingsViewController;
and the Implementation
#implementation MainViewController
-(void)showCountdownView {
self.slidingMainMenuViewController.countdownView.hidden = NO;
NSLog(#"Showing Countdown");
}
-(void)hideCountdownView {
self.slidingMainMenuViewController.countdownView.hidden = YES;
NSLog(#"Hiding Countdown");
}
-(void)viewDidLoad {
[super viewDidLoad];
self.settingsViewController.delegate = self;
self.slidingMainMenuViewController.delegate = self;
}
the problem is that the NSLogs above is not being called at all, can any one help me ?
Thanks
UPDATE: Since i have more that 20 different views that needs to be called, i created this method
- (UIView *) getPresentedMenu:(NSString *) menuIdentifer withMenuTag:(int) menuTag withAViewController:(UIViewController*) menuViewController andMenuDelegate:(id) menuDelegate {
menuViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:Nil] instantiateViewControllerWithIdentifier:menuIdentifer];
menuViewController.view.tag = menuTag;
if (self.viewBeingCalledBySwipe == NO) {
menuViewController.view.frame = CGRectMake(0, menuViewController.view.frame.size.height, menuViewController.view.frame.size.width, menuViewController.view.frame.size.height);
} else if (self.isItRightSwipe == YES) {
menuViewController.view.frame = CGRectMake(-menuViewController.view.frame.size.width, 0, menuViewController.view.frame.size.width, menuViewController.view.frame.size.height);
} else if (self.isItRightSwipe == NO) {
menuViewController.view.frame = CGRectMake(menuViewController.view.frame.size.width, 0, menuViewController.view.frame.size.width, menuViewController.view.frame.size.height);
}
[self.view addSubview:menuViewController.view];
[self addChildViewController:menuViewController];
[menuViewController didMoveToParentViewController:self];
UIView *view = menuViewController.view;
return view;
}
So when ever i need a certain view controller, i just call this function
self.childView = [self getPresentedMenu:#"Settings" withMenuTag:SETTINGS_TAG withAViewController:self.settingsViewController andMenuDelegate:self.settingsViewController.delegate];
but this method is not assigning the delegate
If settingsViewController is an IBOutlet, you have to add IBOutlet to it's declaration and connect it using the storyboard or xib.
#property (nonatomic, strong) IBOutlet SettingsHubViewController * settingsViewController;
But if it's not an Outlet, you have to allocate it before set it's delegate.
self.settingsViewController = [[SettingsHubViewController alloc] init];
self.settingsViewController.delegate = self;
You should also verify that your - (IBAction)switchAction:(id)sender IBAction is correctly connected in the storyboard or xib.
When you initialize your SettingsViewController, make sure that you do it using the storyboard method and not [[SettingsViewController alloc] init].
First set a Storyboard ID directly in your storyboard view:
Then use this to settingsViewController:
self.settingsViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:NULL] instantiateViewControllerWithIdentifier:#"SettingsViewController"];
Replace MainStoryboard_iPhone with your Storyboard name.
Hope that helps!
// If u are using View controller
SettingsHubViewController *settingVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"yourStoryBoardIdentifier"];
settingVC.delegate = self;
// If u are using XIB load the NIB after that set the settingVC.delegate = self;
its working for me (I created OverLay view and loaded in main class)
I have two views. The first one is having 2 buttons and second one is having a label and a button. Am trying to change the text of the label based on the button pressed. In the code below, am calling an instance of second view and trying to change text in the label. But the problem is the text is not changing. Will appreciate if some one can help me here
#interface firstview : UIViewController {
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
}
#property(nonatomic, retain) IBOutlet UIButton *button1;
#property(nonatomic, retain) IBOutlet UIButton *button2;
-(IBAction)push:(UIButton *)sender;
#end
#import "firstview.h"
#import "secondview.h"
#implementation firstview
#synthesize button1;
#synthesize button2;
-(IBAction)push:(UIButton *)sender{
button1.tag = 1;
button2.tag = 2;
if(sender.tag == button1.tag){
secondview *v2 = [[secondview alloc]initWithNibName:#"secondview" bundle:Nil];
v2.title =#"first button";
v2.l1.text = #"BUTTON1";
[self.navigationController pushViewController:v2 animated:YES];
[v2 release];
}
else if(sender.tag == button2.tag){
secondview *v2 = [[secondview alloc]initWithNibName:#"secondview" bundle:Nil];
v2.title =#"Select";
v2.l1.text = #"BUTTON2";
[self.navigationController pushViewController:v2 animated:YES];
[v2 release];
}
}
#end
second view
#import <UIKit/UIKit.h>
#interface secondview : UIViewController {
IBOutlet UIButton *b2;
IBOutlet UILabel *l1;
}
#property(nonatomic, retain)IBOutlet UIButton *b2;
#property(nonatomic, retain)IBOutlet UILabel *l1;
-(IBAction)pop:(id)sender;
#end
#import "secondview.h"
#implementation secondview
#synthesize b2;
#synthesize l1;
-(IBAction)pop:(id)sender{
}
#end
At the time you are trying to set the label text, the view has not been loaded in your second view controller, so the label is nil.
Try moving the calls to after you push the view controller, or, better still (since only a view controller should change its views properties) have string properties on the second view controller for the label values, and set the label text value inside viewWillAppear.
From jrturton: The view is not been loaded in your second view controller, so the label is nil. What can you is declare a NSString property in secondview and you can set value of this property from firstview and then you can set this value to the label in viewWillAppear or viewDidLoad method.