I'm new to this, and I'm banging my head on a wall, so any help you can provide would be appreciated.
My app is downloading a series of coordinates and titles which I'm turning into MKAnnotations. I've implemented the MKAnnotation protocol well enough because it's stopped complaining about that, but here's the code:
Annotator.h:
#import <Foundation/Foundation.h>
#import "MapKit/Mapkit.h"
#interface Annotator : NSObject <MKAnnotation>
+ (Annotator *) createAnnotator:(CLLocationCoordinate2D *)coordinate
withTitle:(NSString *)title
andSubtitle:(NSString *)subtitle;
#property (nonatomic, strong) NSString *myTitle;
#property (nonatomic, strong) NSString *mySubtitle;
#property (nonatomic) CLLocationCoordinate2D *coordinate;
#end
Pretty boring so far. Here's Annotator.m:
#import "Annotator.h"
#implementation Annotator
#synthesize myTitle = _myTitle;
#synthesize mySubtitle = _mySubtitle;
#synthesize coordinate = _coordinate;
+ (Annotator *)createAnnotator:(CLLocationCoordinate2D *)coordinate
withTitle:(NSString *)title
andSubtitle:(NSString *)subtitle
{
Annotator *annotation = [[Annotator alloc] init];
annotation.myTitle = title;
annotation.mySubtitle = subtitle;
annotation.coordinate = coordinate;
return annotation;
}
- (NSString *)title
{
return self.myTitle;
}
- (NSString *)subtitle
{
return self.mySubtitle;
}
#end
Right now, I've got most of the other code in a central view controller, so as soon as the HTTP request returns with the data, I iterate through it, creating my MKAnnotation objects, and then do this for each one:
[self.territoryMap addAnnotation:locationPin];
...where self.territoryMap is an outlet to the MKMapView I dragged into my storyboard, and locationPin is the MKAnnotation object I created with my Annotator implementation above.
Some of the solutions I've looked at have MKMapViewDelegate methods in place, but it seems to me that they shouldn't be necessary, as I'm just looking for the default behavior. I put in one delegate that I found which allowed me to change the color of the user's location pin, but that's not what I'm worried about.
Is there something else I need to be doing? I'm confused! Thanks for whatever help you can provide!
You have to set the MapViews delegate. Then it should work fine.
Alternatively look into this: http://maybelost.com/2011/01/a-basic-mapview-and-annotation-tutorial/
It looks pretty much like that what you are trying to do!
Related
I have a window with a large NSTextFeildCell, where text can be modified. Upon clicking a button another window appears where the text from the original window can be used some how. The issue I am having is when I attempt to retrieve that text the log spits out...
" -[NSTextView stringValue]: unrecognized selector sent to instance 0x100151860"
Fallowed by a long trace...
I have tried to solve this several different ways but with no luck.
currently,
First window controller
.h
#import <Cocoa/Cocoa.h>
#class NextWindowController;
#interface TextViewWindowController : NSWindowController
#property (nonatomic, weak) NextWindowController *NextWindow;
#property (nonatomic, weak) IBOutlet NSTextFieldCell *txtTextView;
- (IBAction)btnClicked:(id)sender;
- (NSString*)getText;
#end
.m
#import "TextViewWindowController.h"
#import "NextWindowController.h"
#implementation TextViewWindowController
#synthesize NextWindow;
- (IBAction)btnClicked:(id)sender{
[NextWindow setCallingWindow:self];
[NextWindow showWindow:self];
}
- (NSString*)getText{
return [_txtTextView stringValue];// there is a problem with the view...
}
#end
Next Window controller
.h
#import <Cocoa/Cocoa.h>
#class TextViewWindowController;
#interface NextWindowController : NSWindowController{
NSMutableString* str;
}
#property (nonatomic, weak) TextViewWindowController *callingWindow;
#end
.m
#import "NextWindowController.h"
#import "TextViewWindowController.h"
#implementation NextWindowController
#synthesize callingWindow;
- (IBAction)btnEnterClicked:(id)sender{
[str setString:callingWindow.txtTextView.stringValue];
}
- (id)initWithWindow:(NSWindow *)window{
self = [super initWithWindow:window];
if (self) {
str = [[NSMutableString alloc] init];
}
return self;
}
#end
I have also tried str = [callingWindow getText] with the same result.
Any help would be very appreciated!
It's not super intuitive to figure out from Apple's documentation, but to get the raw string value of a NSTextView (which inherits from NSText), just use:
[_txtTextView string];
And since you're using properties, it might be smarter to use the accessor in your function, like this:
- (NSString*)getText{
return [self.txtTextView string];
}
I recently started learning Objective-C and Cocos-2D. I tried to define my own method for automating the creation of sprites.
I added my own class where I'll create other automation methods as well. Anyhow my .h file looks like this:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#interface ActionsClass : CCNode {
}
#property (nonatomic, strong) CCSprite* createSprite;
#property (nonatomic, strong) CCSprite* spriteName;
#property (nonatomic, strong) NSString* pngName;
#property (nonatomic) CGPoint* spriteCoordinate;
- (CCSprite *)createSprite: (CCSprite *)spriteName: (NSString *)pngName: (CGPoint *)spriteCoordinate;
#end
And the .m is:
#import "ActionsClass.h"
#implementation ActionsClass
#synthesize createSprite = _createSprite;
#synthesize spriteName = _spriteName;
#synthesize pngName = _pngName;
#synthesize spriteCoordinate = _spriteCoordinate;
- (CCSprite *)createSprite: (CCSprite *)spriteName: (NSString *)pngName: (CGPoint *)spriteCoordinate
{
if (!_createSprite)
{
_createSprite = [[CCSprite alloc] init];
_spriteName = [CCSprite spriteWithFile:_pngName];
_spriteName.position = ccp(_spriteCoordinate->x, _spriteCoordinate->y);
[self addChild:_spriteName];
}
return _createSprite;
}
#end
In the main .m file where I want to call the method:
[self createSprite: saif: #"saif.png": ccp(100,100)];
This would give the warning that xcode didn't find the instance method createSprite and defaults it to id
Thanks a lot and sorry if the font or the formatting of the question aren't super neat.
Your method declaration is wrong, so you wont be able to call it.
It should be:
- (CCSprite *)createSprite:(CCSprite *)spriteName pngName:(NSString *)pngName coord:(CGPoint *)spriteCoordinate;
And called like:
[self createSprite:someSprite pngName:somePNGName coord:someCoord];
Edit: I didn't see that you were trying to call this from another class. To do that you will need to import the ActionsClass header file, and call this method on an instance of ActionsClass, e.g.
ActionsClass *actionsClassObject = [[ActionsClass alloc] init];
[actionsClassObject createSprite:someSprite pngName:somePNGName coord:someCoord];
Right before my model class sends the variable stringToDisplay, NSLog shows me that it has a value. But when I try to use it in my ViewController, I just get (null). Any thoughts about what I'm doing wrong?
(The good news is that, while working on this, I had sort of a breakthrough in understanding how models and controllers relate to each other. I'm still a complete newbie, but I don't feel quite as lost as I did.)
Here's what I think is the relevant code:
CalculatorBrain.h
#import <Foundation/Foundation.h>
#interface CalculatorBrain : NSObject
#property (nonatomic) NSMutableString *stringToAdd;
#property (nonatomic,strong) NSString *stringForDisplay;
- (double)performOperation:(NSString *)operation withArray:(NSMutableArray *)particularStackYouNeedToPopOff;
CalculatorBrain.m
#implementation CalculatorBrain
#synthesize stringToAdd = _stringToAdd;
#synthesize stringForDisplay = _stringForDisplay;
#synthesize whatHappenedSinceLastClear = _whatHappenedSinceLastClear;
- (double)performOperation:(NSString *)operation withArray:(NSMutableArray *)particularStackYouNeedToPopOff
{
<long code that I think doesn't matter because this NSLog produces exactly what I want it to:>
NSLog(#"%#",stringForDisplay);
return result;
}
CalculatorViewController.h
#import <UIKit/UIKit.h>
#interface CalculatorViewController : UIViewController
#property (nonatomic) NSArray *arrayOfDictionaries;
#property (nonatomic) NSDictionary *dictionary;
#property (weak, nonatomic) IBOutlet UILabel *variablesUsed;
#property (nonatomic, strong) NSString *operation;
#end
CalculatorViewController.m
#import "CalculatorViewController.h"
#import "CalculatorBrain.h"
#interface CalculatorViewController ()
#property (nonatomic,strong) CalculatorBrain *brain;
#end
#implementation CalculatorViewController
#synthesize display = _display;
#synthesize history = _history;
#synthesize brain = _brain;
#synthesize operation = _operation;
- (IBAction)operationPressed:(UIButton *)sender
{
NSString *otherString=[self.brain stringForDisplay];
if (self.userIsEnteringNumber) [self enterPressed];
NSString *operation = sender.currentTitle;
double result = [self.brain performOperation:operation withArray:[self.brain whatHappenedSinceLastClear]];
self.display.text = [NSString stringWithFormat:#"%g",result];
self.history.text = otherString;
NSLog(#"%#",otherString);
}
And the NSLog in that last line of code give me (null).
Any thoughts?
Maybe I'm missing something but your property is declared in the class extension of CalculatorBrain so nobody outside CalculatorBrain.m knows about this property.
So if you want to expose this property to other objects, you will have to declare it in CalculatorBrain.h instead.
Oh - your declaration of the property whatHappenedSinceLastClear isn't exposed to other classes that import CalculatorBrain.h because you put the property declaration in an interface extension in the .m file, which other classes will not see.
To make it publicly accessible move the #property line for whatHappenedSinceLastClear to CalculatorBrain.h, not the .m file.
I can guess that problem lies in the way you assign your stringForDisplay, eg.:
if you use something like
stringForDisplay_ = anotherString;
setter for property doesn't fire, so you have to retain your variable yourself otherwise it'll live just until your method finishes;
If so - use property setters, eg.:
self.stringForDisplay = anotherString;
that way ARC will do all the memory management.
It really depends how you set stringForDisplay inside the performOperation:withArray: method.
for a blind guess, try using
NSString *otherString = self.brain.stringForDisplay;
after this line
double result = [self.brain performOperation:operation withArray:[self.brain whatHappenedSinceLastClear]];
Here is a case where I am passing some parameters to a method, and then assigning the parameter values to local ivars and properties:
- (void) assignOwnerView:(UIView*)oView andPosition:(menuPosition)position withTopView:(UIView*)topView {
self.topView = topView;
self.ownerView = oView;
self.position = position;
<< --- other code --- >>
}
The interface for these properties is this (UPDATED with SYNTHESIS)
#interface MenuVC (){
UIView *ownerView_;
UIView *topView_;
menuPosition position_;
}
#property (nonatomic, retain) UIView *ownerView;
#property (nonatomic, retain) UIView *topView;
#property (assign) menuPosition position;
#end
#implementation MenuVC
#synthesize list, menuDelegate;
#synthesize ownerView = ownerView_;
#synthesize topView = topView_;
#synthesize position = position_;
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
{...
The enum is defined here:
typedef enum {
above,
below,
centered
} menuPosition;
After executing the three assignments, at a breakpoint in the debugger, the values are as shown below:
The received parameter values look okay, but the assigned values of the ivars ownerView_ and position_ are not right. On the other hand, topView is okay.
The same thing happened when I assigned directly to ivars rather than properties.
I started seeing this problem when I upgraded to Lion (10.7.3) and XCode 4.3.1. It was working okay before then. I see this at other spots in my app, and I don't see any pattern to it yet.
ARC is not being used.
I reported this problem before, but didn't get an answer. In this case, the problem description is a simpler. That might make it easier to see what the problem is.
UPDATE -- header file added
#import <UIKit/UIKit.h>
#class MenuVC;
#protocol menuDelegateProtocol
typedef enum {
above,
below,
centered
} menuPosition;
- (void) didSelectItemFromMenu:(MenuVC *)menu atIndex:(NSUInteger) index;
#end
#interface MenuVC : UITableViewController {
NSArray *list;
float extendedHeight;
id<menuDelegateProtocol> menuDelegate;
}
#property (nonatomic, retain) NSArray *list;
#property (nonatomic, assign) id<menuDelegateProtocol> menuDelegate;
- (id) initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
- (void) hide;
- (void) unhide;
- (void) assignOwnerView:(UIView*)oView andPosition:(menuPosition)position withTopView:(UIView*)topView;
#end
You didn't synthesized the properties.
Put:
#synthetize ownerView = ownerView_;
#synthetize topView = topView_;
#synthetize position = position_;
After "#implementation MenuVC".
I changed the debugger to GDB from LLDB. This seems to be a problem with LLDB. I'm not seeing this now.
I rarely ask questions, but this one is frustrating me as I can not find an answer anywhere!
I just need to call the function in GameChallenges.m and return the value to the view controller. GameChallenges.m will be called by different view controllers, thats why its separate. Please help!
I have a separate class file called GameChallenges.
This has a function/method in it:
in the .h
#class StatsViewController;
#interface GameChallenges : NSObject {
StatsViewController* statsController;
NSString* challengeTitle;
}
#property (nonatomic, retain) IBOutlet StatsViewController* statsController;
#property (assign) NSString* challengeTitle;
-(NSString*)checkChallenge:(int)challegeID;
#end
in the .m
#import "GameChallenges.h"
#import "StatsViewController.h"
#implementation GameChallenges
#synthesize challengeTitle,statsController;
-(NSString*)checkChallenge:(int)challegeID{
if(challegeID==1){
self.challengeTitle = #"Some Text.";
return challengeTitle;
}else if(challegeID==2){
self.challengeTitle = #"Some Other Text.";
return challengeTitle;
}
}
From a view controller called StatsViewController I am calling this method
in the .h
#class GameChallenges;
#interface StatsViewController : UIViewController {
UILabel* challengeIDDescText;
}
#property (nonatomic, retain) IBOutlet UILabel* challengeIDDescText;
#property (nonatomic, retain) IBOutlet GameChallenges* challenges;
#end
in the .m
[challenges checkChallenge:tempString];
challengeIDDescText.text = challenges.challengeTitle;
Your code is quite weird, I'd say this is what's happening:
-[GameChallenges checkChallenge] seems to expect an int and you call it with a variable called tempString that I guess is an NSString *. More likely than not, your method is ending without assigning challengeTitle and without a valid return value. Fix it with return nil as last statement and passing an int.
This kind of problems are very easy to solve using the debugger.
Also, have a look to Apple samples.
I'm beginner in objective-C, however, code in the GameChallenges.m looks weird to me... Wouldn't this be better?
challengeIDDescText.text = [challenges checkChallenge:challengeId];