iphone sdk - problem pasting into current text location - iphone

I'm trying to paste text right into where the cursor currently is. I have been trying to do what it says at:
- http://dev.ragfield.com/2009/09/insert-text-at-current-cursor-location.html
The main deal is that I can't just go textbox1.text (etc) because the textfield is in the middle of a custom cell. I want to just have some text added to where the cursor is (when I press a custom key on a keyboard).
-I just want to paste a decimal into the textbox...
The error I get is:
2010-05-15 22:37:20.797 PageControl[37962:207] * -[MyDetailController paste:]: unrecognized selector sent to instance 0x1973d10
2010-05-15 22:37:20.797 PageControl[37962:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[MyDetailController paste:]: unrecognized selector sent to instance 0x1973d10'
Note: I have access to the textfield tag (if that helps?)
I'm a little past the beginner stage in objective-c, but still not great. My code is currently below, and at https://gist.github.com/d634329e5ddf52945989
Thanks all.
MyDetailController.h
#interface MyDetailController : UITableViewController <UITextFieldDelegate,UINavigationControllerDelegate>
{
//...(lots in here)
}
#end
#interface UIResponder(UIResponderInsertTextAdditions)
- (void) insertText: (NSString*) text;
#end
MyDetailController.m
#implementation MyDetailController
//.... (lots in here)
- (void)addDecimal:(NSNotification *)notification {
// Apend the Decimal to the TextField.
//savedAmount.text = [savedAmount.text stringByAppendingString:#"."];
NSLog(#"Decimal Pressed");
NSLog(#"tagClicked: %d",tagClicked);
switch (tagClicked) {
case 7:
//savedAmount.text = [savedAmount.text stringByAppendingString:#"."];
break;
case 8:
//goalAmount.text = [goalAmount.text stringByAppendingString:#"."];
break;
case 9:
//incrementAmount.text = [incrementAmount.text stringByAppendingString:#"."];
break;
case 10:
//incrementAmount.text = [incrementAmount.text stringByAppendingString:#"."];
break;
}
[self insertText:#"."];
}
-(void)textFieldDidBeginEditing:(UITextField *)textfield{
//UITextField *theCell = (UITextField *)sender;
tagClicked = textfield.tag;
NSLog(#"textfield changed. tagClicked: %d",tagClicked);
}
#end
#implementation UIResponder(UIResponderInsertTextAdditions)
- (void) insertText: (NSString*) text
{
// Get a refererence to the system pasteboard because that's
// the only one #selector(paste:) will use.
UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
// Save a copy of the system pasteboard's items
// so we can restore them later.
NSArray* items = [generalPasteboard.items copy];
// Set the contents of the system pasteboard
// to the text we wish to insert.
generalPasteboard.string = text;
// Tell this responder to paste the contents of the
// system pasteboard at the current cursor location.
[self paste: self];
// Restore the system pasteboard to its original items.
generalPasteboard.items = items;
// Free the items array we copied earlier.
[items release];
}
#end

UIViewController is a UIResponder... but it's not the UIResopnder that should receive the insertText: message. You want to call insertText: on the UITextField itself. If you take a look at UIResponder.h you'll see the following comment near the paste: method
// these methods are not implemented in NSObject
Meaning that it's not necessarily safe to call them on just any UIResponder. They can only safely be called on subclasses such as UITextField and UITextView which actually implement them. This was a really strange design decision on Apple's part.

Related

How to use Custom Picker View with search bar in ios

I am beginner in iOS In one of my activity I have created custom picker view with search bar .....Actually I am using YHCPicker class for custom picker view and search bar and apply this on TextField Code here.....
UITextField* StateId;
StateId=[[UITextField alloc]initWithFrame:CGRectMake(150,540,150,30)];
StateId.font = [UIFont boldSystemFontOfSize:12.0];
StateId.borderStyle = UITextBorderStyleLine;
StateId.delegate = self;
StateId.tag = 4;
[scrollview addSubview:StateId];
and I am using this delegate for this textfield....
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField.tag==4)
{
View_StateID = [[NSMutable Array]allocinitWithArray:#"Delhi", #"Rajasthan"......, nil];
NSLog(#"dict is %#",View_StateID);
PickerView* objYHCPickerView = [[PickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 480) ];
objYHCPickerView.delegate = self;
[self.view addSubview:objYHCPickerView];
[objYHCPickerView showPicker:View_StateID];
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
then call method ShowPicker in YHCPickerView and I show this picker with search bar on my view.....like as image
Now in this image when we search in search bar first time then get desired state successfully and click on done or search button(from keybord) then get value on StateID textfield but when we again tap on text field then my image as well as but tap on searchbar then get error like this....
-[CALayer keyboardWillShowNotification:]: unrecognized selector sent to instance 0xaad8950
So I don't know what problem ....so solve this problem...
Errors like this can be caused by non properly retaining objects:
The object is released and freed.
Its memory is reused for some random other object.
Then, when a selector is called on the original object -> boom.
One thing to check is if all your #properties that hold objects in your class are strong and not assign.
What's also smart to do is setting an exception breakpoint
Finally, try to find out to which object this pointer 0xaad8950 (did) belong(s): Place breakpoints further and further, before the app crashes and look around at the objects' address you're having.
Good luck!

Saving an array object as a string within a picker view?

So I am working with a pickerview and need a string to equal one of several things that I have stored in an array. The pickerview code for the components looks like this.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
switch (row) {
case 0:
image.image = image1;
email = EmailArray[1];
break;
case 1:
image.image = image2;
email = EmailArray[3];
break;
case 2:
image.image = image3;
email = EmailArray[5];
break;
}
NSLog(#"%#", email)
}
This code works just fine as far as I can tell. The NSLog here returns the correct email every time. The user then presses a button that utilizes the "email" string. Here is the first part of that code.
- (IBAction)sendFeedback:(id)sender
{
NSLog(#"%#", email);
}
Only here the NSLog does not return the correct email. It just freezes the program and gives me a threading error that points at that NSLog. Am I not passing the array object to the string correctly?
If I change the code to this it works just fine.
switch (row) {
case 0:
image.image = image1;
email = #"testEmail#gmail.com";
break;
After this both NSLogs will display the test email.
Please help me figure out this problem. If you need more information just ask.
EDIT
Here is the beginning of my ViewController.h file.
#interface ViewController : UIViewController
<UIPickerViewDataSource, UIPickerViewDelegate, UIImagePickerControllerDelegate> {
NSMutableArray *EmailArray;
}
Here is where email is declared in the ViewController.h.
#implementation ViewController
NSString *email;
The error I get looks like this.
Thread 1:EXC_BAD_ACCESS(code=2, address=0x14)
You should not declared email as an instance var. An NSString must be declared as a property with copy modifier
#property (copy, nonatomic) NSString* email;
Your variable is not retained in memory, hence the crash.
You have two options
Add [email retain] after you assign it
Enable ARC and it will retain that variable for you.

UILabel category and setFont: crash

I created UILabel category which would do extra work when font property is changed.
I have chosen category over sublassing so I do not have to change class for all labels in my all XIB files. I just add this category declaration to the prefix header and category is visible in the whole project scope.
Implementation file:
//
// UILabel+XIBCustomFonts.m
#import "UILabel+XIBCustomFonts.h"
#implementation UILabel (XIBCustomFonts)
BOOL comes_from_nib = NO;
-(id)initWithCoder:(NSCoder *)aDecoder_{
self = [super initWithCoder:aDecoder_];
if (self) {
comes_from_nib = YES;
}
return self;
}
-(void)setFont:(UIFont *)font_{
[super setFont:font_];
NSLog(#"Setting from for label from XIB for name:%# size: %.1f - do font theme replacement if needed", self.font.fontName, self.font.pointSize);
}
#end
The surprising thing is the crash with following log:
-[UIButtonLabel setFont:]: unrecognized selector sent to instance 0x9ad1b70
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButtonLabel setFont:]: unrecognized selector sent to instance 0x9ad1b70'
Where did UIButtonLabel came form?
It happens even if I do extra Class checking in setFont: setter:
if ([self class] != [UILabel class] || !comes_from_nib) {
[super setFont:font_];
return;
}
Is there any way to override setFont: setter in UILabel without subclassing?
You cannot call super methods in categories! Never!
This is not possible when you use a category to augment a class' functionality, you are not extending the class, you are actually wholly overriding the existing method, you lose the original method completely. That's why your error appears.

textFieldDidBeginEditing: for more than one textfield

I am fairly new to iphone programming and here I am facing some issues. Now in my application, I have two textfields and I want to fire an event while second textfield starts editing. now I am using following function
- (void)textFieldDidBeginEditing:(UITextField *)textField
but the thing is the event is being fired when the first textfield starts editing. It does not wait for the second text field. Is there any way I can use this function for the second textfield or may be somehow could know and pass it the value of the active textfield?
I tried writing the name of the textfield instead of (UITextField *)textField in the function but still the same result.
If I were you , I would set a tag (in Interface Builder) of the second textField to 2, or something similar. Then you can just do this:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField.tag == 2) {
//this is textfield 2, so call your method here
}
}
EDIT: Please do this to see if the method is even called:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(#"The method was called");
}
For Swift 2.2
func textFieldDidBeginEditing(textField: UITextField) {
if textField.tag == 2 {
//this is textfield 2, so call your method here
}
}
That delegate method is gonna get called everytime the editing of ANY text field is started, so it should be you who controls what is done when this happens. I suggest you to do something like:
-(void)textFieldDidBeginEditing: (UITextField *)textField
{
if (textField == mySecondTextField)
{
//Do what you need
}
else
{
//Do nothing
}
}
I hope it helps you!
Utilitize the tag property in Interface Builder to identify your view objects in your application at runtime. It will make life a lot easier, especially when you get ready to localize your application for different languages.
In your header file for your view controller
#define kUsernameField 100
#define kPasswordField 101
#define kStartButton 300
In the view controller implementation file
- (void)textFieldDidBeginEditing:(UITextField *)textField {
switch (textField.tag) {
case kUsernameField:
// do user name stuff
break;
case kPasswordField:
// do password stuff
break;
default:
NSLog(#"No case statement for %#", [textField description]);
break;
}
}
You will find a lot of tutorial out there that use the title field of UIButton to identify them. For example:
- (IBAction)buttonTouchUp:(id)sender {
UIButton *button = (UIButton *)sender;
// don't like
if ([button.currentTitle isEqualToString:#"Start"] == NSOrderedSame) {
// because if localize your for other language then you will have
// include code for those other language
// French: Démarrer
// Spanish: Inicio
// blah blah blah
}
// better
if (button.tag == kStartButton) {
// very simple, no code changes for localization
// blah blah blah
}
}
If you are creating the object with code, you can set the tag:
button.tag = kStartButton;
// or
[button setTag:kStartButton];
You must declare first UITextFieldDelegate in your controller .h
And set the delegate of your text field. ex. myInput.delegate = self;
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:myInput])
{
NSLog(#"test");
}
}
This works perfectly for me.
Have you checked if your second textViews delegate is set to self ? I had the same issue where I had forgotten to set the delegate of other textFields and hence the delegate method was not firing.
Please have a look to my answer in this Question, it's exactly what you're looking for
Objective C: what is a "(id) sender"?

iPhone Dev = maps and deselecting annotations

I am successfully drawing annotations on a map using an array of annotations. I can even click on the annotation and change it’s colour or image. My problem arises when the use selects the second annotation and I want to dynamically change the colour or image of the first one back to a non-selected colour/image. I can get the array of all the annotations and work through the array but once I try to set the colour or image ot the array I get a similar error.
for (MKAnnotationView *ann in map.selectedAnnotations){
if ([ann isMemberOfClass:[Place class]]) {
place = (Place *)ann;
if (currentPlaceID != place.placeID) {
UIImage *i = [UIImage imageNamed:#"pin.png"];
ann.image = i;
}
}
the above code works ok until I get to ann.image = i; then it errors. The errors I get are:-
-[Place setImage:]: unrecognized selector sent to instance 0x4514370 Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '** -[Place setImage:]:
unrecognized selector sent to instance 0x4514370'
Please advise as I have been going around in circles on this one for 2 days now!!!!
Any ideas on how best to do this?
thanks in advance
Do you have a property on the class Place called image?
Something like... #property (nonatomic, retain) UIImage* image; and is it properly synthesized? #synthesize image;?
The error is pretty straight forward, some object is receiving a message that it doesn't respond to, namely 'setImage' which is invoked by the .image.
Here is your code:
1. for (MKAnnotationView *ann in map.selectedAnnotations) {
2. if ([ann isMemberOfClass:[Place class]]) {
3. place = (Place *)ann;
4. if (currentPlaceID != place.placeID) {
5. UIImage *i = [UIImage imageNamed:#"pin.png"];
6. ann.image = i;
7. }
8. }
9. }
What I can see:
ann is an MKAnnotationView (from map.selectedAnnotations)
you are typecasting your annotation to a place on line 3 (is this right? Does Place subclass MKAnnotationView?)
you are properly setting the image to the annotation
What this means:
If Place is indeed a subclass of MKAnnotationView, you hid the setImage (somehow) method
If Place is NOT a subclass of MKAnnotationView, you've added an invalid annotation to the annotations (sure) that you're trying to treat as an annotation.
I finally figured out how to do this. As usual it's not that hard once you know how. Just thought I would pass this on.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
NSLog(#"here I am in set selected");
if (YES == selected)
{
NSLog(#"I am selected");
}
else
{
self.backgroundColor = [UIColor clearColor];
NSLog(#"not selected");
}
}