i'm new in Objective C . What i'm going to do is simple just to animate keyboard up when textfield is focused and shrink when it's not. I already followed some other tutorial on how to set up this step by step but it not working.The event textViewDidBeginEditing is never get called when textfeld is focus.
#interface ViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *cCodeTextField;
#property (weak, nonatomic) IBOutlet UITextField *jidTextField;
- (IBAction)nextBtnTapped:(id)sender;
#end
I'm also set the delegate to the textfield but it's not working.
- (void)viewDidLoad {
[super viewDidLoad];
[self addTextFieldBorder:_jidTextField];
[self addTextFieldBorder:_cCodeTextField];
_jidTextField.delegate = self;
}
-(void) textViewDidBeginEditing:(UITextView *)textView {
NSLog(#"Enter");
}
It looks like your ViewController class is implementing methods from the wrong delegate. It is implementing UITextViewDelegate methods when it should be implementing UITextFieldDelegate methods.
Note that 'jidTextField' is of type UITextField.
Your delegate method is called 'textViewDidBeginEditing' which is a UITextViewDelegate method and takes a UITextView as a parameter.
The issue here is that your class is implementing delegate functions for UITextViewDelegate and not UITextFieldDelegate.
The correct method definition is:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
Here is a link to the documentation for the correct delegate:
https://developer.apple.com/reference/uikit/uitextfielddelegate
Hope this helps!
Related
I have UIView, what called Popup and poping from UIViewContorller(ParentVC)
On UIView I have 4 buttons. When buttons is pressed, it needs to open new Controllers from(ParentVC). I am using Delegate, were is my mistake?
//Popup.h
#protocol PopupDelegate
#required
- (IBAction)stepOfRestoration:(id)sender;
- (IBAction)clientCall:(id)sender;
- (IBAction)readyTo:(id)sender;
- (IBAction)givePhone:(id)sender;
#end
#interface Popup : PSCustomViewFromXib
#property (nonatomic, assign) id <PopupDelegate> delegate;
#property (strong, nonatomic) IBOutlet UIView *view;
- (IBAction)stepOfRestoration:(id)sender;
- (IBAction)clientCall:(id)sender;
- (IBAction)readyTo:(id)sender;
- (IBAction)givePhone:(id)sender;
In .m i have this:
#synthesize delegate;
....
- (IBAction)stepOfRestoration:(id)sender {
[self.delegate buttonPressed];
}
And this is Parent .m
...
CGRect rect = CGRectMake(0,0,200,300);
Popup *popup1 = [[Popup alloc] initWithFrame:rect];
popup1.delegate = self;
....
-(void)buttonPressed {
[self performSegueWithIdentifier:#"infoSegue" sender:nil];
}
So were is my mistake?
You don't have a method called buttonPressed in your protocol, you need to call a method in your protocol, e.g.
Popup.m
- (IBAction)buttonPressed:(id)sender {
[self.delegate stepOfRestoration:sender];
}
Parent.m
- (IBAction)stepOfRestoration:(id)sender {
// some code
}
Link to long winded but hopefully helpful tutorial, good luck.
In your Parent .m, you must conform all the methods which are defined in protocol. In your Parent.m file, buttonPressed method is not present in protocol. So update the name of below method with buttonPressed as follow:-
Update below code at Popup.h while declaring PopupDelegate methods
- (IBAction)stepOfRestoration:(id)sender;
With
-(void)buttonPressed;
you shouldn't add IBAction methods in your protocol
instead add following methods corresponding each button action
//Popup.h
#protocol PopupDelegate
#required
- (Void)stepOfRestoration:(id)sender;
- (Void)clientCall:(id)sender;
- (Void)readyTo:(id)sender;
- (Void)givePhone:(id)sender;
#end
and call these protocol methods in corresponding button action methods
e.g. //Popup.m
- (IBAction)stepOfRestoration:(id)sender {
[self.delegate stepOfRestoration:sender];
}
and //Parent.m
-(Void)stepOfRestoration:(id)sender{
// code here
}
Is there a notification or callback when a UIView is added in other UIView which has a UIViewController. We can get a UIView's ViewController, if it has one, via nextResponder. (Reference)
But depending on nextResponder is not reliable, if the UIView is not been added into a View which has ViewController, this method fails. For example, when we are calling from the cell's responder in UITableViewDataSource's cellForRowAtIndexPath. Because by the time of calling cellForRowAtIndexPath, the cell being dequeued hasn't been added into UITableView yet. However, we can call that method in - tableView:willDisplayCell:forRowAtIndexPath:, because by the time of calling - tableView:willDisplayCell:forRowAtIndexPath:, the cell is already being added into TableView.
So if you have ViewA which is the view of ViewControllerA and you want to add the ViewB you can subclass ViewB
#protocol ViewBDelegate
- (void) viewAddedToSuperview:(ViewB*)sender;
#end
#interface ViewB: UIView
#property (nonatomic, assign) id< ViewBDelegate > delegate;
#end
#implementation
- (void)didMoveToSuperview {
[super didMoveToSuperview];
[delegate viewAddedToSuperview:self];
}
#end
and in ViewControllerA you implements the protocol ViewBDelegate.
This is just an example of my idea.
Let me know in the comments it is can help you, otherwise I will try to propose other solutions depending on your goals.
I'm new to iOS programming, and I'm not sure why my textDidChange function is not firing. Searched online a bunch, but can't find out what's different between my code and everyone else's. Here's what my .h and .m files look like for this view controller:
CategoryTableViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface CategoryTableViewController : UITableViewController
#property (weak, nonatomic) IBOutlet UIBarButtonItem *btnBack;
#property (weak, nonatomic) IBOutlet UISearchBar *txtSearchBar;
#property (strong,nonatomic) NSArray *allCategories;
#property (strong,nonatomic) NSMutableArray *filteredCategories;
//A stack containing the parent categories used to get to the current category.
#property (strong, nonatomic) NSMutableArray *parentCategories;
#end
Relevant code from CategoryTableViewController.m:
-(void)txtSearchBar:(UISearchBar*)txtSearchBar textDidChange: (NSString*)text
{
//do something
}
I used Xcode's ctrl+click+drag to create the reference to the search bar in the header file. I put breakpoints and print statements at the start of the textDidChange code, but none of it ever gets called. Any ideas?
You need to set the delegate property of txtSearchBar to use the delegate methods.
Make sure you add
self.txtSearchBar.delegate = self;
in ViewDidLoad()
and the delegate method
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
//Do something
}
If you're using a delegate method be sure to set the delegate property on the instance that needs to call the delegate so it knows there is a delegate and where to send actions.
if you're using Interface Builder and not delegate, you need to create an IBAction function, or you can use a UIControl's subclass addTarget() method to create a callback for a given event type.
Add
self.txtSearchBar.delegate = self
in viewDidLoad().
how could we use the UIScrollViewDelegate methods on a tableView that is added to a UIViewController? It works fine when I subclass the UITableViewController, but in my case, the tableView is added inside a UIViewController. The delegate and datasource are linked to self, I added UIScrollViewDelegate as a protocol, but the delegate methods are not recognized by the viewController.
Thanks
UITableViewDelegate inherits from UIScrollViewDelegate.
If you determine that object is delegate of table view, it would be also a delegate of scrollView.
Here is how to get this done in two steps:
ViewController.h
Your UIViewController must implement both the UITableViewDelegate and UIScrollViewDelegate. If you are working with interface builder, you will also have an IBOutlet for the UITableView:
#interface ViewController : UIViewController<UITableViewDelegate, UIScrollViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableView;
ViewController.m
In your implementation code, you have to specify that ViewController is the tableview's delegate. You also need to implement one of UIScrollView's delegate methods to be notified of the scroll:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"Scrollview did scroll");
}
In file .h I have:
#protocol VVInformationTableViewControllerDelegate;
#interface VVInformationTableViewController : UITableViewController <UITextFieldDelegate, UIGestureRecognizerDelegate, UIPickerViewDataSource, UIPickerViewDelegate, UITableViewDelegate>
#property (strong, nonatomic) VVUser* currentAttendee;
#property (weak, nonatomic) id<VVInformationTableViewControllerDelegate> delegate;
In file .m:
In viewDidLoad:
self.tableView.delegate = self;
and I have method:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self dismissKeyboard];
NSLog(#"HEJ");
}
But when I dragging my tableView (no matter if keyboard is show or not) this method didn't work. I looked for this problem but I couldn't find asnwer.
EDIT:
I make this (scrollViewWillBeginDragging) method in parentViewController and it works. But when I call in this method in parentViewController [self.infoTableView dismissKeyboard] (VVInformationTableViewController as childViewController) which is in childView It didn't work. For example if I try use dismissKeyboard:
- (void)dismissKeyboard {
[self.textField resignFirstResponder];
NSLog(#"%#", self.textField.text);
}
in childView then self.textField.text in NSLog is good, but when I try call it in parentView then it is nil, so resignFirstResponder on this textfield didn't work.
I make protocol with method dismissKeyboard in .h of childViewController and:
-(void)textFieldDidBeginEditing:(UITextField *)textField{
self.textField = textField;
self.tableView.scrollEnabled = NO;
}