Objective-C: using methods from other files - objective-c

I have looked at all the other people who had this error pop up, and I know it is a pathing error, and yes I have tried to quit and reboot it, I checked the paths were using up-to-date files, and most of what people suggested with no success. I am trying to get methods from TapViewController to run in JumpController. I simplified the method I want to be called to make it easier to find the issue, but still am having trouble. Here is the relevant code I have so far:
TapViewController.h
-(void)hello;
TapViewController.m
-(void)hello {
NSLog(#"Hello");
}
JumpController.h
#import <UIKit/UIKit.h>
#import 'TapViewController.h'
#property (strong, nonatomic) TapViewController *TapView;
#property (strong, nonatomic) JumpController *JumpControl;
JumpController.m
-(void)viewDidLoad {
self.JumpControl = (TapViewController *)[UIApplication sharedApplication].delegate;
self.TapView = [[TapViewController alloc] init];
[self.JumpControl.TapView hello];
}
I grabbed most of this code from what others have said to do, so I don't really know if some of it is irrelevant or if all will help in the situation. Basically, the app crashes when it loads stating [AppDelegate TapView]: unrecognized selector sent to instance.... Let me know if I am doing anything wrong or if I left out relevant code!
UPDATE: Using what others have said and from my own personal changes, It seems like the problem is not only with self.JumpControl = (TapViewController *)[UIApplication sharedApplication].delegate but also with self.JumpControl as a whole. Because I created the TapViewController *TapView in the .h file there is no reason to use self.JumpControl which caused problems on the order of views that showed up. I will mark almas as correct, but I wanted to clarify what more needed to be done.

Your problem is here: "self.JumpControl = (TapViewController *)[UIApplication sharedApplication].delegate;". You are trying to cast your AppDelegate to TapViewController, thats why it crashes. AppDelegate is not a view controller. Your error message [AppDelegate TapView]: unrecognized selector sent to instance clearly states that AppDelegate doesn't recognize the method "TapView", it is because app delegate is not an instance of "TapViewController".

Related

Category header imports not working

I have a workspace that has two projects in it. The first project was essentially a test and develop project where I got things working before worrying about tying everything together for real. The second project is bringing all my individually developed view controllers together in a storyboard.
On one of the view controllers I have a bunch of swipe gestures with quite a bit of UIView animation calls nicely formatted for readability and therefore taking a lot of space. I elected to move them out as a category.
The problem is that the compiler is not seeing the instance variable declarations in the main header file.
What has me pulling my hair out is that I did this in the first project and it all worked fine. So I'm carefully comparing the contents of my second project to the first and I see no differences.
Here're some file snippets to help demonstrate how/where I'm defining things, and then snippets of code in the category file that is attempting to access them:
GSBViewController.h
#interface GSBViewController : UIViewController
#property (strong, nonatomic) IBOutlet UISegmentedControl *roundPicker;
#property (strong, nonatomic) IBOutlet UIView *roundsSectionView;
GSBViewController.m
#import "GSBViewController+Swipe.h"
#interface GSBGameBuilderViewController ()
{
UIBarButtonItem *rightGatherBarButton;
NSInteger previousRound;
}
#end
#implementation GSBViewController
#synthesize roundPicker;
#synthesize roundsSectionView;
GSBViewController+Swipe.h
#import "GSBViewController.h"
#interface GSBViewController (Swipe)
- (void)establishSwipeGestures;
#end
GSBViewController+Swipe.m
#import "GSBViewController+Swipe.h"
#implementation GSBViewController (Swipe)
- (void)establishSwipeGestures
{
UISwipeGestureRecognizer *swipeLeft =
[[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(roundsSectionLeft:)];
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[swipeLeft setNumberOfTouchesRequired:1];
[roundsSectionView addGestureRecognizer:swipeLeft];
// bunch-o-code snipped -- for the time being it's actually all commented out
// as a test and because the LLVM compiler was giving up after too many errors
// and I wanted to see if there was more it would like to tell me about this first --
// and very representative -- problem.
}
#end
The complaint from the compiler is "Use of undeclared identifier 'roundsSectionView'"
If I option-click on the use of roundsSectionView in that line of code where I'm adding the gesture recognizer to it the pop-up correctly describes it as declared in GSBViewController.h
So I'm stumped.
Is there something I can do in Xcode (4.3.2 at the time of this posting :-) to let me see what the included files are? Or is there something non-file-based that is needed to tie a category into the class it's augmenting? I don't remember anything like that being necessary before. In fact, the way I generated the files for this category was through Xcode's File -> New File... Objective-C Category template. Then I just copied the contents of the old ...+Swipe.h and ...+Swipe.m files and pasted them into their respective files in the new project.
A synthesized ivar is private. The compiler won't allow you to access it anywhere execept in the #implementation block where it's created. Neither categories nor subclasses can access the ivar directly; they must use the property: [self roundsSectionView].
There's a slight possibilty that earlier Clangs didn't make synthesized ivars private. Either that or you weren't really doing exactly the same thing in the earlier project.
What #Jacques Cousteau says is correct.
Since you just defined a property and no backing ivar, the category won't be able to access it. If you use self.roundsSectionView it will use the getter method generated for the property and hence it will work.
Or you could define a backing variable in your interface
#interface GSBViewController : UIViewController
{
UIBarButtonItem *roundsSectionView;
}
In this case the categories will be able to access the variable. But not any other class.

Why can't I get this initialized?

I have been trying to figure this out for DAYS. I am a beginner, so please bear with me. I have read a bunch of articles on delegation but I still just don't get it. Any help would be much appreciated.
Header
#protocol MidiInit <NSObject>
#end
#interface CBAppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) id midiDelegate;
-(id) initWithDelegate :(id <MidiInit>) delegate;
#end
Implementation
#synthesize midiDelegate;
-(id) initWithDelegate:(id<MidiInit>)delegate
{
if ((self = [super init]))
{
self.midiDelegate = delegate;
midi = [[MidiClass alloc] initWithDelegate://not sure what to put here];
}
return self;
}
It would help to know what you are trying to achieve, but from what you're showing us, pretty much everything looks wrong :-)
Are you showing us the application delegate? If so, what is the point of delegating to another delegate from the application delegate? It doesn't look like a standard approach.
Second, you probably don't want a 'strong' reference to a delegate, could lead to memory leaks.
But honestly, I don't think the real problem here is what you're pointing too, the entire approach seems to be wrong. Tell us more about what you're trying to achieve and I'll try to update my answer accordingly.

UITextField.text keeps returning null

I have create a delegate for this UIViewController, and I am passing in an employee name to set a UITextField. But, no matter what I do, as you can see, it results in (null). However, I have a datelabel that gets populated in a similar way, but it works correctly. I include that for reference. I am missing something simple. But, now I am blind from staring at it...
Any ideas? Thanks.
#interface TimesheetEntryViewController()
#property (weak, nonatomic) IBOutlet UILabel *datelabel;
#property (weak, nonatomic) IBOutlet UITextField *employeeTextField;
#end
#implementation TimesheetEntryViewController
#synthesize tableView = _tableView;
#synthesize datelabel = _datelabel;
#synthesize employeeName = _employeeName;
#synthesize employeeTextField = _employeeTextField;
-(void)setEmployeeNameString:(NSString *)lemployeeNameString
{
self.employeeTextField.text = lemployeeNameString;
NSLog(#"%#:%#", lemployeeNameString, self.employeeTextField.text);
}
Result: 2012-05-02 08:42:50.137 rbTimesheet[7855:11303] Bob Smith:(null)
-(void)changeDateViewController:(ChooseDateViewController *)ntvc didChooseDate:(NSDate *)lDate
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateStyle = NSDateFormatterMediumStyle;
self.datelabel.text = [NSString stringWithFormat:#"%#",
[df stringFromDate:lDate]];
[self dismissModalViewControllerAnimated:YES];
}
I have mapped the textfield through drag and drop in xcode 5 ,So it is not synthesized but i also tried to resolve this issue by synthesizing it manually but it not worked.
I resolved this issue by assigning empty string in the text field object in viewDidLoad method
_txtDialedNumber.text=#"";
Note:-While using this i am not synthesizing the textfield object and it is working for me in Xcode 5.0(testing in iPhone 5 IOS 6)
So I had the same issue and after googling and coming across multiple posts like this my issue was a fellow developer was doing this(which worked in previous versions of xCode somehow) which I cut and pasted from a similar project
-(void)setTextFieldDelegates{
self.usernameTextField = [[UITextField alloc] init];
self.passwordTextField = [[UITextField alloc] init];
[self.usernameTextField setDelegate: self];
[self.passwordTextField setDelegate: self];
}
So even though the outlet was connected he was somehow re assigning it and it was working.
Check if the connection between the text field and the outlet is correct in the Interface Builder.
Check if you have subclassed the uitextField by using
textField=[[UITextField alloc]init].
If you have done that, try removing it from the code. I was having the same problem and I got it working by removing these lines.
Maybe you are calling setEmployeeNameString: before the view is loaded? That should give you null as a result.
It looks as if you are overriding the automatic setter/getter for your textfield. The whole point of using #synthesize is to save you some code and hassle from setting them yourself.
My guess is you aren't setting the delegate right. You are saying that the current view controller text field should get the date, then you dismiss the modal view killing the value saved there.
I would change your reference from weak to strong and get rid of your setter. It is being done for you already, no need to clutter things up.

Why can't I access variables when I subclass a customised UIViewController?

I am new to iOS dev and apologies if the answer is obvious...but it isn't to me.
I have an APP with a Navigation controller at its root.
I have many very similar looking areas of the app to be created.
These are each to be UItableviewcontroller which has had a fair bit of customising done to allow buttons and other controls beside the tableview which has been reduced in size to allow for controls beside and below it.
The buttons, text, background etc etc and the data that gets loaded must all be individual to the particular are of the APP.
I created a UItableviewcontroller subclass by simply adding a new file subclass in Xcode.
I created my interface in the xib...created all the methods to drive what I need to in it.
Looks great...all seems fine. If I use it alone...works well.
Problem: I can't figure out how to subclass my custom sub-classed UITVController!
None of its properties are available from inside the new sub-class.
I clearly don't understand how things work here.
I have tried adding a new file > UIViewcontroller sub-class and changing the superclass to my custom superclass...to no avail. No properties accessible.
I have dug and dug and become more confused than anything else.
Is someone kind enough to help me get it right. Frustration is building.
Thanks
Keispe
EDIT:
Whoa found the problem. I have had Xcode open for many many days with several projects open.
It had totally weirded out!
In fact jrturton and eugene...I did know what I was doing (I thought I was going crazy...done this before in my app and suddenly no worky) Xcode had totally lost it's brains!
Anyone seen Xcode do that before??? using 4.1
Bloody hell that wasted a heap of valuable time including yours.
Thanks fellas
When you subclass anything, you can access your parent's class properties by addressing self via dot syntax
#interface BaseClass : NSObject {
#public
NSString *baseclassString;
}
#property (nonatomic, copy) NSString *name;
#end
.h
#interface HigherClass : BaseClass
#end
.m
#implementation HigherClass
- (id)init {
self = [super init];
self.name = #"Hola";
self->baseclassString = #"Hola";
return self;
}
- (void)viewDidLoad {
NSLog(#"name: %#", self.name);
}
#end
This all isn't 100% memory clean but you've gotta get a hang of what is happening here and adjust it properly to your application.

UITextView returns number instead of text

stackoverflow, google and coffee have failed to find the answer, however......
specialViewController.h has...
#interface SpecialViewController : UIViewController {
UITextView *messageBody;
}
#property (nonatomic, retain) UITextView *messageBody;
specialViewController.m has....
#implementation SpecialViewController
#synthesize messageBody;
plus....
-(IBAction)executeSpecial:(id)sender{
[self.messageBody resignFirstResponder];
NSString *message = messageBody.text;
NSLog(#"returned text is %#", message);
}
shows "returned text is 148082" or some random number dependent on the text entered. I just cannot, for the life of me, find out why the text I am entering is not being shown.
Generally, problems like this are from other part of the code that you may not expect. I noticed that you don't have your UITextView marked as an IBOutlet. Are you adding it programmatically? If so, can you give us the code for that.
Sorry Gents, problem was decaf coffee! During the course of my coding, I repurposed the variable and this ultimately conflicted. It turns out that I was getting exactly what I asked for. I always find it strange that my applications never do what I want, only what I tell them to......