How do i correct this warning? - objective-c

I was searching for a Done button for the Number Pad,then i saw this question:
How to show "Done" button on iPhone number pad
I copied Archie's answer code into mine,and i get 2 warnings in this area:
- (void)textFieldDidBeginEditing:(NSNotification *)note {
[self updateKeyboardButtonFor:[note object]];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (void)keyboardDidShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
The warnings are:
Incompatible Objective-C types initializing 'struct NSNotification *', expected 'struct UITextField *'
How can i correct that? I tried to switch with a UITextField but it all messed up

As BoltClock suggested, it does seem a bit strange that Archie use a delegate method's name as a notification handler. The problem might be stemming from the fact that you must be adopting the UITextFieldDelegate protocol. If you've done so, remove the line observing the notification,
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(textFieldDidBeginEditing:)
name:UITextFieldTextDidBeginEditingNotification
object:nil];
and then edit make the textFieldDidBeginEditing: method while becoming the delegate of the text fields,
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self updateKeyboardButtonFor:textField];
}
Or alternatively, rename the occurrences of textFieldDidBeginEditing: with some other suitable method name

textFieldDidBeginEditing is not a notification, it is a delegate method. The expected signature is - (void)textFieldDidBeginEditing:(UITextField *)aTextField

Related

Cocoa NSOpenGLView - [win setDelegate:view ] shows error. How to delegate manually?

I'm programming in Eclipse (not Xcode) on Yosemita 10.10...
I try to catch MouseMoved event, but it not called (mouseDown, mouseDragged - works fine). So I'm using this example code from here
http://lists.apple.com/archives/mac-opengl/2003/Feb/msg00069.html
but compiller show error on
[app setDelegate: view];
(- cannot initialize a parameter of type 'id' with an lvalue of type 'NSView *')
If I comment this line - it's work, but mouseMoved don't calling.
Please help! I'm newbie in objective-c
OS X does not automatically track the mouse movement events for you unless you request them.
In order to receive mouseMoved: events, you should add an NSTrackingArea to your subclass of NSOpenGLView. For example:
- (void)awakeFromNib {
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.frame options:NSTrackingActiveAlways|NSTrackingMouseMoved owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
}
After that, your mouseMoved: method will be called.
- (void)mouseMoved:(NSEvent *)theEvent {
NSLog(#"moved");
}
You can optionally implement updateTrackingAreas if you need to update your tracking area manually when the view resizes. For details, please refer to Using Tracking-Area Objects.

How to properly use delegation for NSTextField

Im trying to implement a delegate for a NSTextField object so I can detect the user input in real time and give some feedback about no allowed input in that particular field.
Especially, I want to simulate the onChange() method from JavaScript, detecting the user input in real time and show him a warning if it is writing a non supported value.
i.e. The app have a text field it only accept numeric values from 0 to 255 (like RGB values) and I want to know when the user is writing not numeric values or out of range values to instantly show him a warning message or change the text field background color, just a visual hint to let him know the input it's wrong.
Like you see on the pictures above, I want to show a warning sign every time the user inputs a forbidden value in the text field.
I have been reading a lot of the Apple's documentation but I don't understand which delegate to implement (NSTextFieldDelegate, NSTextDelegate, or NSTextViewDelegate), also, I have no idea how to implement it in my AppDelegate.m file and which method use and how to get the notification of user editing.
Right now, I already set the Delegate in my init method with something like this [self.textField setDelegate:self]; but I don't understand how to use it or which method implements.
I found a solution using the information posted in this question... Listen to a value change of my text field
First of all I have to declare the NSTextFieldDelegate in the AppDelegate.h file
#interface AppDelegate : NSObject <NSApplicationDelegate, NSTextFieldDelegate>
After that, I have to instantiate the delegate for the NSTextField object I want to modify while the user update it in the AppDelegate.m file.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self.textField setDelegate:self];
}
Finally, I implement the methods to detect field editing with the changes I want to set.
- (void)controlTextDidChange:(NSNotification *)notification {
NSTextField *textField = [notification object];
if ([textField doubleValue] < 0 | [textField doubleValue] > 255) {
textField.textColor = [NSColor redColor];
}
}
- (void)controlTextDidEndEditing:(NSNotification *)notification {
NSTextField *textField = [notification object];
if ([textField resignFirstResponder]) {
textField.textColor = [NSColor blackColor];
}
}
Make your class conform to the NSTextFieldDelegate protocol. It need's to be that protocol because in the documentation it says the type of protocol the delegate conforms to.
#interface MyClass : NSObject
And implement the delegate's methods (just add them to your code). Example
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor
{
}
EDIT:
I think in your case it would be better to replace the TextField for a TextView and use a NSTextViewDelegate, in the delegate, the method of most interst of you should be
- (BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString
{
BOOL isValid = ... // Check here if replacementString is valid (only digits, ...)
return isValid; // If you return false, the user edition is cancelled
}

Detecting a change to text in UITextfield

I would like to be able to detect if some text is changed in a UITextField so that I can then enable a UIButton to save the changes.
Instead of observing notifications or implementing textField:shouldChangeCharacterInRange:replacementString:, it's easier to just add an event target:
[textField addTarget:self
action:#selector(myTextFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
- (void)myTextFieldDidChange:(id)sender {
// Handle change.
}
Note that the event is UIControlEventEditingChanged and not UIControlEventValueChanged!
The advantages over the other two suggested solutions are:
You don't need to remember to unregister your controller with the NSNotificationCenter.
The event handler is called after the change has been made which means textField.text contains the text the user actually entered. The textField:shouldChangeCharacterInRange:replacementString: delegate method is called before the changes have been applied, so textField.text does not yet give you the text the user just entered – you'd have to apply the change yourself first.
Take advantage of the UITextFieldTextDidChange notification or set a delegate on the text field and watch for textField:shouldChangeCharactersInRange:replacementString.
If you want to watch for changes with a notification, you'll need something like this in your code to register for the notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldDidChange:) name:UITextFieldTextDidChangeNotification object:theTextField];
Here theTextField is the instance of UITextField that you want to watch. The class of which self is an instance in the code above must then implement textFieldDidChange, like so:
- (void)textFieldDidChange:(NSNotification *)notification {
// Do whatever you like to respond to text changes here.
}
If the text field is going to outlive the observer, then you must deregister for notifications in the observer's dealloc method. Actually it's a good idea to do this even if the text field does not outlive the observer.
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Other dealloc work
}
For that, first you need to have your textfield have it delegate reference assigned. And the delgate, should preferably be, the vew controller which is the files owner of the view.
Which goes like
myTextField.delegate = myViewControllerReferenceVariable
And in your viewController interface, tell you will be implementing UITextFieldDelegate by
#interface MyViewController:UIViewController<UITextFieldDelegate>
And in your view controller implementation override
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
So the code will look like
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
text = [textfield.text stringByReplacingCharactersInRange:range withString:string];
if (textfield == refToTextFieldYouWantToCheck) {
if ( ! [textToCheck isEqualToString:text] ) {
[theButtonRef setEnabled:YES];
}
}
return YES; //If you don't your textfield won't get any text in it
}
You can also subscribe to notification which is sort of messy IMHO
You can find how to do it here.
Swift 3.0
Process 1
Create IBOutlet of UITextfiled and Add Target to text field.
m_lblTxt.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControlEvents.editingChanged)
func textFieldDidChange(textField:UITextField)
{
NSLog(textField.text!)
}
Process 2
m_lblTxt.delegate = self
//MARK: - TextField Delegates
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
print(textField.text!)
return true
}
This can be accomplished in Interface Builder on the Editing Changed event of UITextField. Drag from it to your code and create an IBAction.
For example:
#IBAction func textFieldChanged(_ sender: UITextField) {
print(sender.text)
}
This event is the same as described in other answers here in that the .text property contains the updated text input when it gets triggered. This can help clean up code clutter by not having to programmatically add the event to every UITextField in the view.
You could create a variable to store the original string, then register with the notification center to receive UITextFieldTextDidChangeNotification event:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateButton:) name:UITextFieldTextDidChangeNotification object:nil];
Then, create a method to receive the notification, and compare the current value of the text field with the original value
-(void) updateButton:(NSNotification *)notification {
self.myButton.enabled = ![self.myTextField.text isEqualToString:originalString];
}
Don't forget to de-register the notification when the view controller is deallocated.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
You can add a class member like this NSString *changeTemp,then
changetemp = textfield;
if( change temp != textfild ){
changetemp=textfild;
NSLog(#" text is changed"
} else {
NSLog(#" text isn't changed"):
}

Parse and create an NSAttributedString when an UITextView's text changes

I'm trying to parse certain parts of the string when a user types into an UITextView or the setText: method is called, and then setting an NSAttributedString back into the text view. However in my current implementation this causes an infinite recursive loop. Since setting the new attributed text causes the text to change (and the notification to fire) whereby I then re-parse the text.
Somebody suggested I use some kind of flag, so while i'm parsing and setting the text, I don't keep doing it. Though this doesn't seem like the optimal solution. Here's a snippet of my code...
CustomTextView.h (UITextView subclass)
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textViewDidChange:) name:NSTextViewTextDidChangeNotification object:self];
CustomTextView textViewDidChange:
- (void)textViewDidChange:(NSNotification *)notification;
{
__block NSString *string = self.text;
dispatch_async(parserQueue, ^{
NSAttributedString *parsedString = [self parseAttributesForString:string];
dispatch_async(dispatch_get_main_queue(), ^{
[self setAttributedText:parsedString];
});
});
}
CustomTextView setText:
- (void)setText:(NSString *)text
{
[super setText:text];
[self textViewDidChange:nil];
}
Thanks!
Okay so first I'd add an observer to the property text instead of subclassing the class and post a notification. Next, I'd just check what class the text object is. I would this by calling [text isKindOfClass:[NSString class]]. By calling this you know whether the object needs to get parsed again.

iphone SDK: Not sure why I am not receiving UITextField events?

I have defined the controller to receive the events.
#interface salesViewController : UIViewController
<UITextFieldDelegate>{
However, none of my events are not firing.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
//this is not getting called
}
In Interface Builder I assigned the TextField delegate to the salesView.
What am I missing?
You have to set the delegate properly. You observe the protocol, but you need to do this:
#interface YourController : UIViewController<UITextFieldDelegate> {
IBOutlet UITextField* field;
}
#end
#implementation YourController
-(void)viewDidLoad
{
[field setDelegate:self];
}
And you will receive the events. Alternatively, you can set the delegate in Interface Builder as well, along with doing it programmatically in loadView, allocating the field and setting the delegate.
Additionally, try to use NSNotificationCenter as little as possible. Notifications are somewhat obsolete unless there isn't really a direct path between you and the object in question. Just a small comment on the answer above.
what are you trying to accomplish? textFieldDidBeginEditing is messaged whenever the user selects the text field. If you are trying to update a label or something as the user makes edits, you need to setup an observer w/ NSNotificationCenter and watch for the notification that is fired whenever this happens.If you take this approach, make sure to remove the observer once you are done with it
for example:
#pragma mark
#pragma mark -
#pragma mark Notification Observers
- (void)addObservers {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldDidChange:) name:#"UITextFieldTextDidChangeNotification" object:nil];
}
- (void)removeObservers {
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UITextFieldTextDidChangeNotification" object:nil];
}
if you need to keep tabs on multiple text fields, do something like this for your selector:
- (void)textFieldDidChange:(NSNotification*)aNotification {
UITextField *textField = (UITextField *)[aNotification object];
if([textField isEqual:usernameTextField])
{
[user setUsername:usernameTextField.text];
}
else if([textField isEqual:phoneNumberTextField])
{
[user setPhoneNumber:phoneNumberTextField.text];
}
}