I m using UISearchBar,and searching is working perfectly but after search clicking on cancel button, didSelectedRowAtIndexPath is not working in UItableView.It is not allowing me to select any row to go further.
Any Idea?
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
isSearchOn = YES;
canSelectRow = NO;
table.scrollEnabled = NO;
}
- (void) doneSearching:(id)sender
{
isSearchOn = NO;
canSelectRow = YES;
table.scrollEnabled = YES;
self.navigationItem.rightBarButtonItem = nil;
[table reloadData];
}
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText
{
if ([searchText length] > 0) {
isSearchOn = YES;
canSelectRow = YES;
table.scrollEnabled = YES;
[self searchMoviesTableView:searchText];
}
else {
isSearchOn = NO;
canSelectRow = NO;
table.scrollEnabled = NO;
}
[table reloadData];
}
- (void) searchMoviesTableView :(NSString*)searchText{
[searchResult removeAllObjects];
for (NSDictionary *artistDic in listOfMovies) {
NSRange titleResultRange = [[artistDic valueForKey:#"artist"] rangeOfString:searchText options:(NSCaseInsensitiveSearch | NSLiteralSearch)];
if (titleResultRange.length > 0)
[searchResult addObject:artistDic];
}
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text = #"";
table.scrollEnabled = true;
[table reloadData];
[searchBar resignFirstResponder];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
here is my mistake...
else {
isSearchOn = NO;
canSelectRow = NO;
table.scrollEnabled = NO;
}
set canSelectRow=YES;
I noticed that you are calling:
searchBar.text = #"";
in searchBarCancelButtonClicked:, which may lead to another call of searchBar:textDidChange:. In searchBar:textDidChange: you set:
canSelectRow = NO;
for strings whose length is 0 (which is true for #""). I wonder is that the root cause?
Related
I am adding a contact picker in my app, however, I do not want the search functionality.
How to hide/Remove the search bar on Contact Picker (ABPeoplePickerNavigationController)?
static BOOL foundSearchBar = NO;
- (void)findSearchBar:(UIView*)parent mark:(NSString*)mark {
for( UIView* v in [parent subviews] ) {
//if( foundSearchBar ) return;
NSLog(#"%#%#",mark,NSStringFromClass([v class]));
if( [v isKindOfClass:[UISearchBar class]] ) {
[(UISearchBar*)v setTintColor:[UIColor blackColor]];
v.hidden=YES;
// foundSearchBar = YES;
break;
}
if( [v isKindOfClass:[UITableView class]] ) {
CGRect temp =v.frame;
temp.origin.y=temp.origin.y-44;
temp.size.height=temp.size.height+44;
v.frame=temp;
//foundSearchBar = YES;
break;
}
[self findSearchBar:v mark:[mark stringByAppendingString:#"> "]];
}
}
call above method after picker is presented as below:
-(void)showPeoplePickerController
{
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
picker.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
// Display only a person's phone, email, and birthdate
NSArray *displayedItems = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty],[NSNumber numberWithInt:kABPersonAddressProperty],nil];
picker.displayedProperties = displayedItems;
// Show the picker
[self presentViewController:picker animated:YES completion:nil];
[self findSearchBar:[picker view] mark:#"> "];
[picker release];
}
-(void)showAddressBook {
ABPeoplePickerNavigationController *addressBook = [[ABPeoplePickerNavigationController alloc] init];
[addressBook setPeoplePickerDelegate:self];
addressBook.delegate = self;
addressBook.navigationBar.topItem.title = #"iPhone Contacts";
UIView *view = addressBook.topViewController.view;
for (UIView *v in view.subviews) {
if ( [v isKindOfClass:[UITableView class]] ) {
CGRect temp = v.frame;
temp.origin.y = temp.origin.y - 44;
temp.size.height = temp.size.height + 44;
v.frame = temp;
}
}
[addressBook release];
}
- (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([navigationController isKindOfClass:[ABPeoplePickerNavigationController class]]) {
UISearchDisplayController *searchDisplayController = navigationController.topViewController.searchDisplayController;
[searchDisplayController.searchBar setHidden:YES];
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Enable copy and paste on UITextField without making it editable
I need to disable editing on UITextField but keep the copy/paste function
when i use
textField.enabled = NO;
then function copy/paste is disabled;
textField.editing = NO;
Xcode write "Assigning to property with 'readonly' attribute not allowed
You can find the help here :
This is subclass of UILabel, you can do exactly similar with UITextField. And Change the class from UITextField to this one.
#implementation CopyableLabel
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if(action == #selector(copy:)) {
return YES;
}
else {
return [super canPerformAction:action withSender:sender];
}
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (BOOL)becomeFirstResponder {
if([super becomeFirstResponder]) {
self.highlighted = YES;
return YES;
}
return NO;
}
- (void)copy:(id)sender {
UIPasteboard *board = [UIPasteboard generalPasteboard];
[board setString:self.text];
self.highlighted = NO;
[self resignFirstResponder];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if([self isFirstResponder]) {
self.highlighted = NO;
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuVisible:NO animated:YES];
[menu update];
[self resignFirstResponder];
}
else if([self becomeFirstResponder]) {
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:self.bounds inView:self];
[menu setMenuVisible:YES animated:YES];
}
}
#end
I use
[textField becomeFirstResponder];
to set keyboard always appears, but the cursor is missing from UITextfield.
how can i set the cursor still show when the keyboard showing up???
#import "Utility.h"
#import "InputViewController.h"
#import "SmsViewController.h"
#implementation InputViewController
#synthesize label,subLabel,textField;
#synthesize input,min,max,inputNo,letterOnly;
#synthesize nextInputViewController;
static NSMutableArray* inputList = nil;
static NSCharacterSet* letterSet;
static NSCharacterSet* digitSet;
+ (NSMutableArray*) inputList {
if (inputList == nil) {
inputList = [[NSMutableArray alloc] init];
}
return inputList;
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// [textField becomeFirstResponder];
// initialize STATIC variables if neccessary
if (inputList == nil) {
inputList = [[NSMutableArray alloc] init];
}
if (letterSet == nil) {
letterSet = [NSCharacterSet alphanumericCharacterSet];
}
if (digitSet == nil) {
digitSet = [NSCharacterSet decimalDigitCharacterSet];
}
min = [[input objectForKey:#"Min"] intValue];
max = [[input objectForKey:#"Max"] intValue];
letterOnly = [[input objectForKey:#"AlphaOnly"] boolValue];
label.text = [input objectForKey:#"Title"];
if (letterOnly) {
subLabel.text = [NSString stringWithFormat:#"Chú ý: Chỉ chấp nhận các ký tự A-Z a-z 0-9"];
}
else {
subLabel.text = [NSString stringWithFormat:#"Chú ý: Chỉ chấp nhận các số từ 0-9"];
}
textField.secureTextEntry = [[input objectForKey:#"Secure"] boolValue];
textField.keyboardType = letterOnly ? UIKeyboardTypeASCIICapable : UIKeyboardTypeNumbersAndPunctuation;
if ([[input objectForKey:#"Input"] count] == 0) {
textField.returnKeyType = UIReturnKeyDone;
} else {
textField.returnKeyType = UIReturnKeyNext;
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// auto focus on textField for waiting input
//[textField becomeFirstResponder];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[input release];
[nextInputViewController release];
[super dealloc];
}
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (theTextField == textField) {
// check maximum length
if ([textField.text length] > max) {
return NO;
}
// check Letter only or Digit only
if ([string length] == 1) {
if (letterOnly) {
if (![letterSet characterIsMember:[string characterAtIndex:0]]) {
return NO;
}
}
else {
if (![digitSet characterIsMember:[string characterAtIndex:0]]) {
return NO;
}
}
}
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
// When the user presses return, take focus away from the text field so that the keyboard is dismissed.
if (theTextField == textField) {
// [textField becomeFirstResponder];
int length = [textField.text length];
if (length < min) {
[Utility showAlert:[NSString stringWithFormat:#"%# phải có chiều dài tối thiểu là %d!", label.text, min]];
return NO;
}
else if ([label.text isEqualToString:#"Nhập mã bí mật mới"] &&
[textField.text isEqualToString:[inputList objectAtIndex:(inputNo-1)]] ) {
[Utility showAlertWithTitle:#"Không hợp lệ" Content:#"Số bí mật mới giống hệt số cũ!"];
return NO;
}
else if ([label.text isEqualToString:#"Xác nhận mã bí mật mới"] &&
![textField.text isEqualToString:[inputList objectAtIndex:(inputNo-1)]] ) {
[Utility showAlertWithTitle:#"Không hợp lệ" Content:#"Mã mới nhập lại không khớp với mã mới nhập lần đầu!"];
return NO;
}
else {
// [textField resignFirstResponder];
[self acceptInput:nil];
}
}
return YES;
}
- (IBAction)acceptInput: (id)sender {
int length = [textField.text length];
if (length < min) {
[Utility showAlert:[NSString stringWithFormat:#"%# phải có chiều dài tối thiểu là %d!", label.text, min]];
return;
}
if ([inputList count] == inputNo) {
[inputList addObject:(NSString*)textField.text];
}
else {
[inputList replaceObjectAtIndex:inputNo withObject:(NSString*)textField.text];
}
NSDictionary* nextInput = [input objectForKey:#"Input"];
if ([nextInput count] == 0) {
SmsViewController* smsViewController = [[SmsViewController alloc] initWithNibName:#"SmsViewController" bundle:nil];
smsViewController.title = #"SMS";
smsViewController.sms = [input objectForKey:#"SMS"];
smsViewController.smsDetails = inputList;
NSString* confirm = [smsViewController.sms objectForKey:#"Confirm"];
[self.navigationController pushViewController:smsViewController animated:YES];
if (confirm == nil || [confirm isEqualToString:#""]) {
// special case
[smsViewController showSMSPicker:smsViewController];
}
[smsViewController release];
}
else {
if (nextInputViewController == nil) {
nextInputViewController = [[InputViewController alloc] initWithNibName:#"InputViewController" bundle:[NSBundle mainBundle]];
nextInputViewController.title = self.title;
nextInputViewController.input = nextInput;
nextInputViewController.inputNo = inputNo + 1;
}
[self.navigationController pushViewController:nextInputViewController animated:NO];
/*
InputViewController *ivController = [[InputViewController alloc] initWithNibName:#"InputViewController" bundle:[NSBundle mainBundle]];
ivController.title = self.title;
ivController.input = nextInput;
ivController.inputNo = inputNo + 1;
[self.navigationController pushViewController:ivController animated:YES];
[ivController release];
*/
}
}
#end
Declare your [textField becomeFirstResponder]; where you hav declared all your textfield delegates like :-
_textFileld =[[UITextField alloc]initWithFrame:CGRectMake(20, 20, 280, 50)];
_textFileld.backgroundColor=[UIColor whiteColor];
_textFileld.borderStyle = UITextBorderStyleRoundedRect;
_textFileld.delegate=self;
_textFileld.clearButtonMode = UITextFieldViewModeAlways;
_textFileld.returnKeyType = UIReturnKeyDone;
_textFileld.placeholder = GlobalButtonString;
[_textFileld becomeFirstResponder];
See if this works ?...
I have problem in my project in the search bar code.
Inside the app I added a search bar to my table view at run time. The search worked fine only 2 times!
If I tried to search for third time the search bar did not allow me to enter any input, and returns me to the home page of the app.
// staffArr Array to store the staff objects
// tableData store the data that will display in table
- (void)viewDidLoad {
[super viewDidLoad];
tableData = [[NSMutableArray alloc] init];
[tableData addObjectsFromArray:staffArr];
self.disableViewOverlay = [[UIView alloc]
initWithFrame:CGRectMake(0.0f,44.0f,320.0f,416.0f)];
self.disableViewOverlay.backgroundColor=[UIColor blackColor];
self.disableViewOverlay.alpha = 0;
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[self searchBar:searchBar activate:YES];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text=#"";
[self searchBar:searchBar activate:NO];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self.tableData removeAllObjects];
if([searchBar.text isEqualToString:#""]|| searchBar.text==nil){
[staffTAB reloadData];
return;}
for(NSInteger i=0;i<staffArr.count;i++)
{
staff *sta = (staff *)[self.staffArr objectAtIndex:i];
NSString *name =sta.staff_name;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchBar.text];
if(r.location != NSNotFound)
{
if(r.location== 0)// checking only the start of the names.
{
[tableData addObject:sta];
}
}
[pool release];
}
[self searchBar:searchBar activate:NO];
[self.staffTAB reloadData];
}
- (void)searchBar:(UISearchBar *)searchBar activate:(BOOL) active
{
self.staffTAB.allowsSelection = !active;
self.staffTAB.scrollEnabled = !active;
if (!active)
{
[disableViewOverlay removeFromSuperview];
[searchBar resignFirstResponder];
}
else
{
self.disableViewOverlay.alpha = 0;
[self.view addSubview:self.disableViewOverlay];
[UIView beginAnimations:#"FadeIn" context:nil];
[UIView setAnimationDuration:0.5];
self.disableViewOverlay.alpha = 0.6;
[UIView commitAnimations];
NSIndexPath *selected = [self.staffTAB indexPathForSelectedRow];
if (selected) {
[self.staffTAB deselectRowAtIndexPath:selected animated:NO];
}
}
[searchBar setShowsCancelButton:active animated:YES];
}
Thanks in advance
I have a login screen with two textfields (username and password). When the user clicks on either textfield, the keyboard appears and everything is fine. However, if the user clicks on the other textfield before clicking Done (on the keyboard) for the first textfield, the text for the username isn't saved. The only way to save the original textfield text is by clicking back on it and selecting Done then.
I would like to disable the other textfield from displaying the keyboard while the first textfield's keyboard is still open, if that makes sense? I know there's ways to stop textfields from being editable but how can I tell when there is already a keyboard open?
Another solution may be to disable the keyboard whenever the user clicks anywhere outside of the textfield? How would I do this?
Here's my code:
textFieldEmail = [[UITextField alloc] initWithFrame:frame];
textFieldEmail.keyboardType = UIKeyboardTypeEmailAddress;
textFieldEmail.returnKeyType = UIReturnKeyDone;
textFieldEmail.tag = 0;
textFieldEmail.delegate = [[UIApplication sharedApplication] delegate];
textFieldPassword = [[UITextField alloc] initWithFrame:frame];
textFieldPassword.keyboardType = UIKeyboardTypeEmailAddress;
textFieldPassword.returnKeyType = UIReturnKeyDone;
textFieldPassword.tag = 1;
textFieldPassword.delegate = [[UIApplication sharedApplication] delegate];
- (BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
Thanks!
I you want this only you can do this like..
#pragma mark -
#pragma mark UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == textFieldEmail){
[textFieldPassword setUserInteractionEnabled:NO];
}
else if(textField == textFieldPassword)
[textFieldEmail setUserInteractionEnabled:NO];
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textFieldEmail setUserInteractionEnabled:YES];
[textFieldPassword setUserInteractionEnabled:YES];
[textField resignFirstResponder];
return YES;
}
But one thing I want to add, blocking UI is a very bad idea in developing iPhone apps. There are many workarounds to achieve your goal. Try not to use the blocking UI.
Hope this helps.
Thanks
you can make some flag, for example smth like neededInfoHasBeenEntered of BOOL type and return it in your textFieldShouldBeginEditing delegate method for all other textFields
I got the same problem and I tried the above code and it was working fine. This code is very much helpful for me.
I have 4 textFields in the my view and I used the code as:
- (void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == eventTextField){
[eventPlaceTextField setUserInteractionEnabled:NO];
[wineryTitleLabel setUserInteractionEnabled:NO];
[vintageTextField setUserInteractionEnabled:NO];
}
else if(textField == eventPlaceTextField)
{
[wineryTitleLabel setUserInteractionEnabled:NO];
[vintageTextField setUserInteractionEnabled:NO];
}
else if(textField == wineryTitleLabel)
{
[vintageTextField setUserInteractionEnabled:NO];
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
int vintageVal = [vintageTextField.text intValue];
if(textField == eventTextField)
{
event.eventName = eventTextField.text;
[eventTextField setUserInteractionEnabled:YES];
[eventPlaceTextField becomeFirstResponder];
[textField resignFirstResponder];
}
else if(textField == eventPlaceTextField)
{
event.eventPlace = eventPlaceTextField.text;
[eventPlaceTextField setUserInteractionEnabled:YES];
[wineryTitleLabel becomeFirstResponder];
[textField resignFirstResponder];
}
else if(textField == wineryTitleLabel)
{
event.eventWinery = wineryTitleLabel.text;
[wineryTitleLabel setUserInteractionEnabled:YES];
[vintageTextField becomeFirstResponder];
[textField resignFirstResponder];
}
else if(textField == vintageTextField)
{
if([vintageTextField.text length] == 4 || [vintageTextField.text length]==0)
{
event.eventVintage = vintageVal;
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"!!!WARNING!!!" message:#"Enter the Vintage in the format 'YYYY'"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return NO;
}
[vintageTextField setUserInteractionEnabled:YES];
[self setViewMovedUp:NO];
[textField resignFirstResponder];
}
return YES;
}
You can approach this on two different ways :
Disable the userInteraction of the textfield on
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if(textfield == textFieldEmail)
{
textFieldPassword.userInteractionEnabled = NO;
}else if(textfield == textFieldPassword){
textFieldEmail.userInteractionEnabled = NO;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
textFieldPassword.userInteractionEnabled = YES;
textFieldEmail.userInteractionEnabled = YES;
}
OR
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
UITextField *theOtherTextField;
if(textView == textFieldEmail)
{
theOtherTextField = textFieldPassword;
}
else if(textfield == textFieldPassword)
{
theOtherTextField = textFieldEmail;
}
return ![theOtherTextField isFirstResponder];
//Return no if the other text field is the first responder
}