Can't set a label in a view - objective-c

I have the following situation. I have a view controller (ContentController) with 3 buttons at the top. Below I added a second view (contentView), this view should display content that are behind those 3 buttons. So every time I press a button, the contentView changes. So what I did was created three addition controllers.
FirstController.m, FirstController.h, FirstController.xib
SecondController.m, SecondController.h, SecondController.xib,
ThirdController.m, ThirdController.h, ThirdController.xib,
in my ContentController.m I added 3 IBActions that handles the change.
#interface ViewController ()
#property (nonatomic,strong) UIViewController *nextController;
#end
#implementation ViewController
#synthesize nextController = _nextController;
-(IBAction)chooseFirstController:(id)sender {
_nextController = [[FirstController alloc] initWithNibName:#"FirstController" bundle:nil];
[self.contentView addSubview:_nextController.view];
}
-(IBAction)chooseSecondController:(id)sender{
_nextController = [[SecondController alloc] initWithNibName:#"SecondController" bundle:nil];
[self.contentView addSubview:_nextController.view];
}
-(IBAction)chooseThirdController:(id)sender{
_nextController = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController" bundle:nil];
[self.contentView addSubview:_nextController.view];
}
My first and ThirdController just showing tableviews inside the contentView of contentController. But in my secondController I used a gridView for displaying items. Now when I press a cell, it should go to a detailViewController, whichs shows more information about that cell. So in my cellForRowAtIndex I did the following.
- (void)gridView:(NRGridView *)gridView didSelectCellAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cell clicked");
PlayerDetailController *playerController = [[PlayerDetailController alloc]initWithNibName:#"PlayerDetailController" bundle:nil];
[playerController setLblTest:#"hooray this works"];
[self.view addSubview:playerController.view];
}
It correctly executes setLblTest and also showing the detailViewcontroller inside my ContentView. But it don't changes the label. to my #"hooray" this works. But although as you can see in my log it passes it correctly.
#synthesize testLabel = _testLabel;
#synthesize lblTest = _lblTest;
-(void)setLblTest:(NSString *)lblTest{
if(![_lblTest isEqual:lblTest]){
_lblTest = lblTest;
}
NSLog(#"log komt %#",lblTest);
[_testLabel setText:lblTest];
}
LOG
RacingGenk[567:c07] log komt hooray this works
Hope this clarifies more my problem
Thank you

To get the label to update, you'll need to change your code to look like this.
self.testLabel.text = lblTest;

Related

label property is nil,container view

Situation:
3 view controllers, white is main, red and blue are embedded (container view controllers)
I select something in red,it switches to blue,I swipe the blue - it goes back and I want to change text in the label to some custom text
Sequence:
So I use delegation and it also works.But when I try to set label's text property(in the method that confirms my protocol) via self.thisLabel.text NSLog says this label is nil, although I have an outlet. If I use something like [self.view viewWithTag:tag] NSLog shows that label is there but I can't set the text, it stays the same.
code in white:
header
#interface ContactsViewController : UIViewController <BlueViewControllerDelegate>
implementation
- (void)adjustLabel:(NSString *)string{
NSLog(#"i am here baby %#",self.thisLabel);
[[self.view viewWithTag:57] setValue:string forKey:#"text"];
}
code in blue:
header:
#protocol BlueViewControllerDelegate <NSObject>
-(void)adjustLabel:(NSString*)string;
#end
and:
#property id<ViewControllerDelegate> delegate;
implementation
- (void)viewDidLoad{
[super viewDidLoad];
UIStoryboard *sB = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
WhiteViewController *WhiteVc = [sB instantiateViewControllerWithIdentifier:#"whiteID"];
self.delegate = WhiteVc;
}
-(void)willMoveToParentViewController:(UIViewController *)parent{
[self.delegate adjustLabel:#"some custom text"];
}
-(IBAction)swipePerformed:(UISwipeGestureRecognizer*)sender{
[self willMoveToParentViewController:nil];
[self.view removeFromSuperview];
[self removeFromParentViewController];
}
Any thoughts?
If I understand your VC hierarchy correctly, the WhiteViewController is the parent of BlueViewController, so you shouldn't instantiate a new one from the storyboard in viewDidLoad but do instead:
WhiteViewController *whiteVc = (WhiteViewController*)self.parentViewController;
self.delegate = whiteVC;
Also, I don't find overriding willMoveToParentViewController particularly useful. You could put your delegate call to your swipe action.

Automatically click segmentControl with index 0 on ViewDidAppear

I am hoping to "automate" a click on the segmentController with the index of 0.
My tabBar-based app has multiple segmentControllers in a tab in the ViewDidAppear method, I would like to automatically have it "click" the first segmented controller.
if (segmentController.selectedSegmentIndex == 0) {
//stuff here
}
if (segmentController.selectedSegmentIndex == 1) {
//stuff here
}
Does anyone know how I might accomplish this? Thank you!
If you're creating it programmatically, you could lazy load it like this:
#interface ExampleViewController : UIViewController
#property (nonatomic, strong) UISegmentedControl *segmentedControl;
- (void)segmentedControlClicked:(UISegmentedControl *)segmentedControl;
#end
#implementation ExampleViewController
- (UISegmentedControl *)segmentedControl
{
if (!_segmentedControl)
{
NSArray *items = #[#"First", #"Second", #"Third"];
_segmentedControl = [[UISegmentedControl alloc] initWithItems:items];
[_segmentedControl addTarget:self
action:#selector(segmentedControlClicked:)
forControlEvents:UIControlEventValueChanged];
[_segmentedControl setSelectedSegmentIndex:0]; // Set Default selection
CGRect frame = _segmentedControl.frame;
frame.origin = CGPointMake(0.0f, 0.0f); // Move to wherever you need it
[self.view addSubview:_segmentedControl];
}
return _segmentedControl;
}
- (void)segmentedControlClicked:(UISegmentedControl *)segmentedControl
{
// Whatever your code is goes here...
}
#end
If you're wanting a method to be called also initially, you can call it within your viewDidLoad: method as such:
- (void)viewDidLoad
{
[self.segmentedControl setSelectedSegmentIndex:0]; // Set desired default index (optional if set in lazy load as shown above)
[self segmentedControlClicked:self.segmentedControl];
}
This would hence simulate a click on desired default index.
Be careful putting the above into viewDidAppear: (you could if you really wanted to) because anytime the view comes to the front, this method will be called (in example, if this view controller presents a modal view controller, once the modal is dismissed, this view controller's viewDidAppear: method will be called).
Cheers!
Set the selectedSegmentIndex property on your UISegmentedControl in your viewDidAppear (or viewDidLoad) method.
self.segmentedController.selectedSegemntIndex = 1;
UISegmentedControl Reference

Property is null after adding subview

I'm launching a UIPopoverViewController that is supposed to draw two buttons (add and delete buttons). The ContentViewController for the UIPopover has a property called outputJackView that is set just before the UIPopoverViewController is launched. This property is necessary for the buttons to draw properly. The problem is right after the first button is added as a subview, the outputJackView is set to null somehow.
Here is the ContentViewController for UIPopoverViewController:
CableConnectionMenuController.h
#import <UIKit/UIKit.h>
#class JackView;
#interface CableConnectionMenuController : UIViewController
{
JackView *outputJackView;
}
#property (nonatomic, weak) id <CableConnectionDelegate> delegate;
#property (nonatomic, strong) JackView *outputJackView;
- (void)setButtonTextWithOutputJack:(JackView *)outputJack withInputArray:(NSMutableArray *)inputArray;
- (void)createAddConnectionButton;
- (void)createDeleteConnectionButton;
#end
CableConnectionMenuController.m
#import "CableConnectionMenuController.h"
#import "JackView.h"
#import "CableDisconnectButton.h"
#implementation CableConnectionMenuController
#synthesize delegate;
#synthesize outputJackView;
...
- (void)viewDidLoad
{
[super viewDidLoad];
//alloc output jack view
self.outputJackView = [[JackView alloc] init];
//set size of popover view in cables view
self.contentSizeForViewInPopover = CGSizeMake(200, 200);
//change view background color
self.view.backgroundColor = [UIColor whiteColor];
}
//this method is called from the class that launches the UIPopoverViewController
- (void)setButtonTextWithOutputJack:(JackView *)outputJack withInputArray:(NSMutableArray *)inputArray
{
//set output jack which will be the same for all inputs
self.outputJackView = outputJack;
//draw add connection button
[self createAddConnectionButton];
//draw delete connection button - not working
//[self createDeleteConnectionButton];
}
- (void)createAddConnectionButton
{
CableDisconnectButton *addConnectionButton = [CableDisconnectButton buttonWithType:UIButtonTypeCustom];
addConnectionButton.frame = CGRectMake(0, 0, 190, 40);
[addConnectionButton setBackgroundImage:[UIImage imageNamed:#"images/cable_connect_button.png"] forState:UIControlStateNormal];
[addConnectionButton setBackgroundImage:[UIImage imageNamed:#"images/cable_connect_button_over.png"] forState:UIControlStateHighlighted];
//add output jack
addConnectionButton.outputJack = self.outputJackView;
//add action to button
[addConnectionButton addTarget:self action:#selector(addConnectionButtonTarget:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"output jack name before: %#", self.outputJackView.jackName);
[self.view addSubview:addConnectionButton];
NSLog(#"output jack name after: %#", self.outputJackView.jackName);
}
The two NSLog's at the end return the name correctly on the first one (before) and return null on the second (after). The jackName properties are NSString's. It's obvious that the property is being set to null after a subview is added, but I can't figure out why that would happen.
Here is the method from the class that launches the UIPopoverViewController in case it matters:
- (void)editCableConnectionsWith:(JackView *)outputJack
{
//launches the note menu popover
self.cableConnectionMenuController = [[CableConnectionMenuController alloc] init];
self.cableConnectionMenuController.delegate = (id)self;
//find appropriate connection to edit
for (JackView *currentJack in jackArray)
{
if (currentJack == outputJack)
{
//create temp array of input jacks to send to cable connection controller
NSMutableArray *inputButtonTempArray = [self returnInputJackArrayWithOutputJack:currentJack];
//set information for creating disconnect buttons in popover
[self.cableConnectionMenuController setButtonTextWithOutputJack:currentJack withInputArray:inputButtonTempArray];
}
}
self.editConnectionsPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.cableConnectionMenuController];
[self.editConnectionsPopoverController presentPopoverFromRect:pulseRing.frame inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
How is the jackName property declared? My guess is that it's a weak reference.
I had a similar issue where a weak reference on a view was reset after the view was added as a subview. My understanding is that a weak reference should only be used when there's a potential retain cycle (e.g. you have a backpack with a reference to a calculator and the calculator points back to the backpack--see the Big Nerd Ranch book).
I'm not quite sure why that's an issue here, but I encountered something similar and figured I'd share.

How to put score in label on second screen after NSTimer?

I have a file (.m) wich is counting the clicks on a button
counter=counter +1;
count.text = [NSString stringWithFormat:#"%i",counter];
After a NSTimer a new screen appears (a new .m / .h / .xib file) but i want the score (clicks on button) in a label on the new screen.
On the first screen header file i'm doing:
IBOutlet UILabel *count;
but after the NStimer countdown i want to display to score on the new screen (screen 2)
Does anyone know how i can do this?
Need some more information? Please ask me!
In your randomMainVoid: action set the property of the label before you push the second view.
I don't know the name of your secondViewController and what you named the label in the secondViewController, so I can't give you exact code here.
Can you tell me what those names are and I will post the code here for you.
You should always name your ViewControllers with a Capital letter like Score, not score. But in either case:
Score *scoreView = [[Score alloc]initWithNibName:#"Score" bundle:nil];
[scoreView.count setText:count.text]; //Replace this with the text you want to pass
[self presentModalViewController:scoreView animated:YES];
Or if your using a NavigationController you could push the view onto the stack:
[self.navigationController pushViewController:scoreView animated:YES];
So, how are you initializing your timer? I assume you are using something like...
timerWithTimeInterval:target:selector:userInfo:repeats:
This method takes a selector, which is called when the timer expires/fires. In this method you should be displaying your view and you can pass the count to the new view you are creating. When your view loads you can set the count to a label on the view.
Just give your second view controller an initializer like:
- (id)initWithScoreText:(NSString*)scoreText {
if ((self = [super initWithNibName:#"MyNibName" bundle:nil])) {
scoreLabelText = [scoreText copy];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
//set the text of the label
scoreLabel.text = scoreLabelText;
}
- (void) dealloc {
//release the string since we copied it
[scoreLabelText release];
[super dealloc];
}
Then in your first view controller, you would do something like:
SecondViewController* newController = [[[SecondViewController alloc] initWithScoreText:count.text] autorelease];
[self.navigationController pushViewController:newController animated:YES];
Edit: updated based on feedback from Paul.s.

How to signal when a view is done and returning?

I'm building an iphone app, and i have my first view call a second view when a button is pressed. The second view is a UIPicker with a button. When the button is pressed, I want to return the data from the UIPicker. How would i do this? Here is the code i have so far:
This is the Button that calls the subview
-(IBAction)DayView:(id)sender{
DayPickerViewController *DPView =[[DayPickerViewController alloc]
initWithNibName:nil bundle:nil];
[self presentModalViewController:DPView animated:YES];
//tried below, doesnt work
//[calc SetDay:[DPView Getrow]];
//DaysButton.titleLabel.text =#"%i",[DPView Getrow];
}
This is the pickerview's code:
-(IBAction)buttonPressed{
NSInteger row = [dayPicker selectedRowInComponent:0];
data = row;
[self dismissModalViewControllerAnimated:YES];
}
The approach you tried first works on Windows where you can open and close a modal dialog in a similar way that you enter and leave a function. However, iOS doesn't work like this.
The simplest approach is to add an instance variable in you second view that refers to the parent view. Then you can notify the parent view by directly calling an instance method:
Main view:
-(IBAction) dayView:(id)sender {
DayPickerViewController *dpView = [[DayPickerViewController alloc]
initWithNibName:nil bundle:nil];
dpView.parent = self;
[self presentModalViewController:dpView animated:YES];
}
-(void) viewController:(DayPickerViewController*)controller
didSelectRow:(NSInteger)row {
// the child view has been dismissed,
// do something with the selected row...
}
Child view:
#property(nonatomic, retain) WoWViewController* parent;
...
#synthesize parent;
-(IBAction) buttonPressed {
NSInteger row = [dayPicker selectedRowInComponent:0];
[self dismissModalViewControllerAnimated:YES];
[self.parent viewController:self didSelectRow:row];
}