Changing text of IBOutlet UILabel via delegate - objective-c

I am trying to change the text of an UILabel that is created via Storyboard. I have two ViewControllers, FirstViewController and SecondViewController. I dismiss the SecondViewController, call the method in the SecondViewController, the delegate method is called in the FirstViewController but the UILabel is nil.
Any idea why?
SecondViewController
-(void)back {
[self.navigationController popToRootViewControllerAnimated:YES];
[self.delegate points:#"10"];
}
FirstViewController
-(void)points:(NSString *)point {
labelPoints.text = [NSString stringWithFormat:#"Points: %#", point];
}

Is your FirstViewController rootViewController? Else pushing to rootViewController will remove First ViewController from stack. From Second View Controller first call delegate and then popViewController as below.
-(void)back {
[self.delegate points:#"10"];
[self.navigationController popViewControllerAnimated:YES];
}

You're popping the VC before you set the value. I would pop from your delegate object like this:
-(void)back {
[self.delegate points:#"10"];
}
-(void)points:(NSString *)point {
labelPoints.text = [NSString stringWithFormat:#"Points: %#", point];
[self.navigationController popToViewController:self animated:YES];
}
If this doesn't solve it, then you likely have another issue besides this one and would have to post more code.

Delay in setting text in UILabel worked for me
For example when delegate calls method like this:
[self.delegate selectedAttendee:dictAttendee];
[self.navigationController popViewControllerAnimated:YES];
This didn't worked for me:
-(void)selectedAttendee:(NSDictionary *)dictAttendee
{
lblMessageTo.text = [dictAttendee objectForKey:#"name"];
}
Solution
-(void)selectedAttendee:(NSDictionary *)dictAttendee
{
[self performSelector:#selector(addTextInMessageTo:) withObject:dictAttendee afterDelay:0.3];
}
-(void)addTextInMessageTo:(NSDictionary *)dictAttendee
{
lblMessageTo.text = [dictAttendee objectForKey:#"name"];
}

Related

How to pass an uiimage to another view controller?

How to pass the uiimage selected in uiimagepickercontroller in MainViewController to SecondViewController? It did push to the SecondViewController, however the uiimage is empty.
I've searched through the web, tried with the solutions but still cannot get it work.
photoImage is the uiimageview I've declared in SecondViewController.
- (void)imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissModalViewControllerAnimated:YES];
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[secondVC.photoImage setImage:[info objectForKey:#"UIImagePickerControllerEditedImage"]];
[self.navigationController pushViewController:secondVC animated:YES];
[secondVC release];
}
A UIImageView in your second view controller doesn't exist until the viewDidLoad method of that controller is called. Put a property into SecondViewController that holds a UIImage, store the reference to the image you want to use in it when you push the view controller (instead of trying to set the image view), and then move your setImage: call into the second view controller's `viewDidLoad``.
Create a shared class that will store the image, and access it wherever you want.
In MainViewController assign that image in that shared class' ivar, and in SecondViewController access it.
Edit :
Below code shows how to implement shared class, this may not be syntactically correct, because currently I am not using mac, so I cant complile.
#interface SomeManager : NSObject
+(id)myImage;
#end
#implementation SomeManager
+(id)myImage{
static id myImage= nil;
#synchronized([self class]){
if (myImage== nil) {
myImage= //put your image here;
}
}
return myImage;
}
#end

presentModalViewController with ARC

I found this snippet of code to use for good transitions:
http://srooltheknife.blogspot.co.uk/2012/03/custom-transition-animation-for-modal.html
The problem is that it uses 'modal' and my program uses ARC so modal has been deprecated in iOS 6.0.
It's only two lines that use modal, so I changed them from-
TransitionController.m:
[self dismissModalViewControllerAnimated:NO];
to:
[self dismissViewControllerAnimated:NO completion:Nil];
and
[self presentModalViewController:modalViewController animated:NO];
to:
[self presentViewController:modalViewController animated:NO completion:nil];
and I execute it with:
FirstPage.m:
#implementation FirstPage
{
TransitionController *tran;
}
- (IBAction)StartGame:(id)sender
{
if (! self.mainPage)
self.mainPage = [[MainGameDisplay alloc] initWithNibName:nil bundle:nil];
[tran presentModalViewController:self.mainPage withPushDirection:kCATransitionFromBottom];
}
StartGame is a button. The program runs perfectly with no errors, but when I click the button nothing happens.
UPDATE:
FirstPage.h:
#import <UIKit/UIKit.h>
#import "MainGameDisplay.h"
#import <QuartzCore/QuartzCore.h>
#import "TransitionController.h"
#interface ViewController : Engine
{ }
- (IBAction)StartGame:(id)sender; //Action connection ID.
#property(nonatomic, readwrite) MainGameDisplay *mainPage;
FirstPage.m:
#implementation ViewController
{
TransitionController *tran;
}
- (IBAction)StartGame:(id)sender {
if (! self.mainPage)
self.mainPage = [[MainGameDisplay alloc] initWithNibName:nil bundle:nil];
tran = [[TransitionController alloc] initWithNibName:Nil bundle:Nil];
[tran presentModalViewController: self.mainPage withPushDirection:kCATransitionFromBottom];
}
When the 'StartGame' button is clicked, the current view is pushed to
the left by the exact same view.
There is a slight fade/glow of the view during the transition.
The direction used in the method is different to the direction of the transition. E.g 'kCATransitionFromBottom' would actually be the view being pushed from the left.
Output with every button click: "Warning: Attempt to present on whose view is not in the window hierarchy!"

How to replace current viewController with a new viewController

I'm trying to replace my current viewController with a new one. I've been able to do this before but I'm having some issues with BAD_ACCESS.
This is the code that will run when I want to replace the current view with a new one.
(The function will be called using a local property "self.some_data" (nonatomic, retain))
-(void) labelSelected:(SomeDataObject*) some_data{
SomeViewController *viewController = (SomeViewController*)[[ClassManager sharedInstance] viewControllerForClassIdentifier:#"com.somename" fromPlistFileName:#"iPhoneScreenList"];
viewController.data = (NSObject*)some_data;
[some_data retain];
//[self.navigationController pushViewController:viewController animated:YES];
UINavigationController *tempNavigationController = self.navigationController;
[[self retain] autorelease];
[tempNavigationController popViewControllerAnimated:FALSE];
[tempNavigationController pushViewController:viewController animated:TRUE];
}
Here everything works fine. The issue is that if I release the new "viewController" it crashes. And if I choose:
[tempNavigationController popViewControllerAnimated:TRUE];
I get some really wierd behaviour where the controller never gets replace and I return to the rootController and the navigation bar has two layers of text on it.
And if I do this:
[tempNavigationController pushViewController:viewController animated:FALSE];
I get BAD_ACCESS and the application chrashes. It worked before but not anymore.
What am I doing wrong?
Thanks!
Use category for controller replace:
// UINavigationController+ReplaceStack.h
#interface UINavigationController (ReplaceStack)
- (void) replaceLastWith:(UIViewController *) controller;
#end
// UINavigationController+ReplaceStack.m
#import "UINavigationController+ReplaceStack.h"
#implementation UINavigationController (ReplaceStack)
- (void) replaceLastWith:(UIViewController *) controller {
NSMutableArray *stackViewControllers = [NSMutableArray arrayWithArray:self.viewControllers];
[stackViewControllers removeLastObject];
[stackViewControllers addObject:controller];
[self setViewControllers:stackViewControllers animated:YES];
}
#end

Pressing a button on a custom keyboard is resulting in "Unrecognized selector being sent to instance error"

I know there are plenty of other questions addressing the same problem, but since I'm using a custom keyboard, I thought my problem would be slightly different.
This is the specific error:
-[EquationTextField element1Pressed:]: unrecognized selector sent to instance 0x4b68ee0
2012-01-02 12:23:44.630 rowQuiz[20975:207] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[EquationTextField element1Pressed:]: unrecognized selector sent to instance 0x4b68ee0'
I have a view controller, quizController. Inside quizController is a custom view, textField (added through interface builder).
When textField is tapped, another custom view, formulaKeyboard, pops up as its keyboard. When a button on the keyboard is pressed, method element1Pressed: is called, and the error described above appears.
Some other questions say that there must be a problem with the retain count, so I tried retaining and releasing quizController in the app delegate, which didn't solve the problem.
It is also possible that I hooked up something incorrectly in Interface Builder; For the custom keyboard, File's owner and the main view are set to class elementKeyboard. For quizController, File's owner is set to quizController and hooked up to it's view.
Below is the code of the textField's class.
EquationTextField.h
#import <UIKit/UIKit.h>
#import "FormulaKeyboard.h"
#interface EquationTextField : UIView <KeyInput> {
FormulaKeyboard *keyboard;
NSString *lastElement;
}
#property (readwrite, retain) UIView *inputView;
#end
EquationTextField.m
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
self.userInteractionEnabled = YES;
[self addGestureRecognizer:
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(becomeFirstResponder)]];
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:#"FormulaKeyboard" owner:self options:nil];
for (id object in bundle) {
if ([object isKindOfClass:[FormulaKeyboard class]])
keyboard = (FormulaKeyboard *)object;
}
self.inputView = keyboard;
keyboard.delegate = self;
}
return self;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
#pragma mark -- KeyInput Protocol Methods
- (void)addElement:(NSString *)elementName {
}
- (void)addCharge:(NSString *)chargeIncrease {
}
- (void) addState:(NSString *)stateName {
}
- (void)deleteCharacter {
}
- (void)dealloc
{
[super dealloc];
}
formulaKeyboard.h
#import <UIKit/UIKit.h>
#protocol KeyInput <UITextInputTraits>
- (void) addElement:(NSString*) elementName;
- (void) addCharge:(NSString*) chargeIncrease;
- (void) addState:(NSString*) stateName;
- (void) deleteCharacter;
#end
#interface FormulaKeyboard : UIView {
id <KeyInput> delegate;
}
#property (nonatomic, retain) id <KeyInput> delegate;
-(IBAction) element1Pressed:(id)sender;
-(IBAction) element2Pressed:(id)sender;
-(IBAction) element3Pressed:(id)sender;
-(IBAction) element4Pressed:(id)sender;
-(IBAction) element5Pressed:(id)sender;
-(IBAction) element6Pressed:(id)sender;
-(IBAction) chargePlusPressed:(id)sender;
-(IBAction) chargeMinusPressed:(id)sender;
-(IBAction) solidSatePressed:(id)sender;
-(IBAction) liquidStatePressed:(id)sender;
-(IBAction) gasStatePressed:(id)sender;
#end
formulaKeyboard.m
- (IBAction)element1Pressed:(id)sender {
[delegate addElement:#"Na"];
}
- (void)element2Pressed:(id)sender {
[delegate addElement:#"N"];
}
- (void)element3Pressed:(id)sender {
[delegate addElement:#"O"];
}
- (void)element4Pressed:(id)sender {
}
- (void)element5Pressed:(id)sender {
}
- (void)element6Pressed:(id)sender {
}
appDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
quizController = [[QuizController alloc] initWithNibName:#"QuizController" bundle:nil];
[self.window addSubview:quizController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[_window release];
[quizController release];
[super dealloc];
}
The action of the keyboard's buttons are pointing to the wrong place. You've probably got them wired to File's Owner inside the FormulaKeyboard nib when they should be wired to the FormulaKeyboard object you're creating inside the nib.
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:#"FormulaKeyboard" owner:self options:nil];
That's being called from EquationTextField, so self would be your instance of EquationTextField. If you're keyboard's targets are pointing there, that's why you get the unrecognized selector exception.
What's happening here is a method called element1Pressed: is being sent to an instance of EquationTextField. You need to actually add the method to the class for it to work. Right now, it's sending the message to the field class, but there's no matching method, so it's throwing an error.
Also, I can't be completely sure about this, since you haven't posted the whole code and/or NIB info, but it seems that you may be going about this the wrong way. You should be using a view controller to handle everything, rather than a custom text field class. I notice that you haven't posted any code for the QuizController class. Once you do so, I may be able to give you more advice.
EDIT: Now that you've posted more code, I think I see the problem. You want the FormulaKeyboard instance to receive the event, but the event is linked to the EquationTextField instance instead. Make sure you wire it to an instance of FormulaKeyboard instead.
On the other hand, it seems that you may not have an instance of FormulaKeyboard in the NIB at all. Add an NSLog after keyboard = (FormulaKeyboard *)object to test if keyboard is ever actually assigned a value. If the NSLog doesn't fire, double-check that you've actually added an instance of FormulaKeyboard to the NIB.

Calling SEL from parentViewController in iOS

I have a ViewController in which I create a Modal ViewController. I have a SEL value in my modal that I set when it is being instantiated from the parent.
setDateViewController.selectorName = #selector(myMethod:);
In my modal I am trying to call this SEL like:
[[self parentViewController] performSelector:self.selectorName withObject:selectedDate afterDelay:.5];
{selectedDate} is obviously a value from my modal.
I don't get any errors or stack, however, this SEL (method) on my parent is never being called. For some reason I think this should work, but something tells me I'm way off track.
Thanks.
I guess [self parentviewcontroller] is not returning anything.
Try UiviewController* v = [self parentviewcontroller]; and check if is nil. Most probably it should be nil. Else if its was pointing to another object of different class then it would have crashed. Please do one thing. YOu should set bot the object and the methd you need to call. IT will solve any issues if it has any.
setDateViewController.selectorDelegate = self;
setDateViewController.selectorName = #selector(myMethod:);
call like this from parent class. So you can dynamically specify the method and the object you want to call gives more flexibility.
and use,
[selectorDelegate performSelector:self.selectorName withObject:selectedDate afterDelay:.5];
this should solve any issues.
Perhaps you would consider added a delegate protocol to your modal that will allow it to call the method on the parent.
Quick (untested) example:
// MyController.h
#protocol MyControllerDelegate;
#interface MyController : UIViewController
{
id<MyControllerDelegate> delegate;
}
#end
#protocol MyControllerDelegate <NSObject>
- (void)methodToCall:(id)sender;
#end
// MyControler.m
#implementation MyController
- (void) loadView
{
[super loadView];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(20.0f, 20.0f, 50.0f, 30.0f);
[btn setTitle:#"blah" forState:UIControlStateNormal];
[btn addTarget:self.delegate
action:#selector(methodToCall:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
#end
// ParentController.h
#interface ParentController : UIViewController<MyControllerDelegate>
{
}
#end
// ParentController.m
#implementation ParentController
- (void)methodToCall:(id)sender
{
NSLog(#"HERE");
}
#end
Just make sure when you are creating your modal controller you set it's delegate to self on the parent:
MyController *controller = [[MyController alloc] init];
controller.delegate = self;
[self presentModalViewController:controller animated:YES];