Im new to objC and Im currently experimenting on UISearchDisplayController. Basically I have an array of string as my data and I use UISearchBarDisplayController to filter my data. Im able to retrieve the correct values when I enter my searchText into the search bar. However, the tableView disappears when my searhBar text is empty.
Would it be possible to prevent the tableView from hiding in this such case. What I want is to just to display all the values in my array in the table if the searchBar text is empty.
I checked the hidden/alpha/frame property of the table and tried to fix my issue here but I think Im in the wrong path here. I'm thinking if i need to subclass the UISearchDisplayController and override the [setActive:YES animated:YES];? Any hint would be appreciated.
You should recieve an event for any change to the search parameters, including when the string is empty.
If you change your implementation of that delegate method to check if the string is empty, you can return the original data instead of the filtered data. This should achieve what you're asking for without the need for subclassing.
I ended up working with UISearchBar and UITable.
So here are the scenarios I encountered.
Display the the UITable when the searchBar is clicked.
UITable shows all the data from my plist when searchText is empty.
UITable shows filtered results from my plist that matches the searchText.
Dismiss the keyboard on press of the search button but don't disable the cancel button on the searchBar.
Remove the UITable when cancel button is press.
I don't have the animation for showing the table for now but this works for me. Also, I allowed the user interaction and scrolling on my table during search so no overlay needed in this case. Glad its working now. :)
I created a sample project for those who might need. Here is the link. Apologies for a messy code and leaks issues. Just posted this to share. :)
You could try by always leaving a zero-space width characters in the search textfield :
static NSString* zsp = #"\u200B";
//In the UISearchBarDelegate
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if(searchBar.text.length == 1 && [text isEqualToString:#""])
{
searchBar.text = zsp;
return NO;
}
return YES;
}
Related
When my application launches, the first NSTextField is being selected like this:
I can edit the NSTextField fine, but when I press enter to end the editing, the text becomes selected again, and the editing does not end.
I followed the Apple tutorial here, and I had the same problem with the text field being perpetually highlighted.
How do I stop this? I would like it so the text field is not the first responder of the app so it's not edited right away, and when it is being edited, clicking outside of the text field will end it. I'm not sure where to put the [[textField window]makeFirstResponder:nil] to stop the editing in the latter case.
I'm running Yosemite 10.10.2.
Your text field is selecting the text, due to the default implementation of becomeFirstResponder in NSTextField.
To prevent selection, subclass NSTextField, and override becomeFirstResponder to deselect any text:
- (BOOL) becomeFirstResponder
{
BOOL responderStatus = [super becomeFirstResponder];
NSRange selectionRange = [[self currentEditor] selectedRange];
[[self currentEditor] setSelectedRange:NSMakeRange(selectionRange.length,0)];
return responderStatus;
}
The resulting behavior is that the field does not select the text when it gets the focus.
To make nothing the first responder, call makeFirstResponder:nil after your application finishes launching. I like to subclass NSObject to define doInitWithContentView:(NSView *)contentView, and call it from my NSApplicationDelegate. In the code below, _window is an IBOutlet:
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
[_menuController doInitWithContentView:_window.contentView];
}
The reason your field is getting focus when the application starts is because the window automatically gives focus to the first control. It determines what is considered first, by scanning left to right, top down (it scans left to right first, since a text field placed at the top right will still get focused). One caveat is that if the window is restorable, and you terminate the application from within Xcode, then whatever field was last focused will retain the focus state from the last execution.
I am using IB, there's a property on NSTextField called Refuses First Responder. Ticking that will prevent the highlighting of the text field immediately after the window is presented. There's some more detailed info about Refuses First Responder in this question.
No need to subclass. Simply set refusesFirstResponder = YES;
NSTextField *textField = [NSTextField new];
textField.refusesFirstResponder = YES;
That's it! Do that and it won't highlight the text in the field.
I've been trying to figure out how to auto erase a string within an NSTextField upon clicking within in it.
For example the current behavior is like this on OSX:
When a user clicks in the cell or the default focus is the cell either the word is sometimes highlighted or the cursor is placed in the middle of the text. The user then needs to use backspace to delete the text (which I'd like to eliminate by automatically removing the text).
Is this a function that is built-in that I'm somehow missing? If not how would I go about it?
As far as I know there is no standard function to delete the text that is in the textfield. Depending on your controller class you can try to work with mouseDown or acceptFirstResponder, but I don't believe this will provide a stable situation.
I would recommend you to start with an empty textfield (setting in xcode) and empty the textfield after the content of the textfield has been processed. For instance:
-(IBAction)addYourTextFieldInWhateverYouWant:(id)sender
{
//copying the string from the textfield
NSString *text = [[self yourTextField]stringValue];
//now you can empty the textfield
[[self yourTextField]setStringValue:#""]
//Do here whatever you need to do with the input from the textfield.
....
}
It doesn't give you exactly what you want, but it provides the user with an empty textfield where the user can immediately type in his/her text when the textfield is clicked upon and the user doesn't need to delete any text in the textfield.
Hope this helps.
Kind regards,
MacUserT
There are plenty of terrible ideas “outside the box”, and this is one of them.
Anyway, make a subclass of NSTextField. Override becomeFirstResponder. If [super becomeFirstResponder] returns YES, set self.stringValue = #"".
Problem
I am having a rather big issue with the iOS7 keyboard appearance. I have a Searchbar on a UIViewController with TableView Delegation/Data Source setup (I am using the self.searchDisplayController delegates as well). I segue from this scene to a prototype tableview to show the results.
Here is the issue:
On first load I can see the keyboard being displayed when I tap into the text field of the UISearchBar. I can type and perform a search with the results being shown in the next scene.
I've added NSNotifications to view the keyboard properties in local methods keyboardWillShow and keyboardWasShown. I can see on the first scene appearance (after the view is completely loaded):
I segue to the result tableview at this point and when I navigate back and touch the text field, my keyboard shows up either fully or partially off-screen:
When I look at the keyboardWillShow notification at this point I can see that my keyboard values are incorrect:
I've researched and tried many possibilities including:
Added the following to my main view controller:
-(BOOL)canResignFirstResponder
{
return YES;
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
Configured the following in my view did load
self.searchDisplayController.searchBar.spellCheckingType = UITextSpellCheckingTypeNo;
self.searchDisplayController.searchBar.autocapitalizationType= UITextAutocapitalizationTypeNone;
self.searchDisplayController.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.searchDisplayController.searchBar.keyboardType = UIKeyboardTypeDefault;
Put in standard stubs for:
-(void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
I've noticed that if I choose a Partial Curl as my segue mode, the keyboard remains accessible when I roll back to the main view controller (but then it was never fully off screen in that case). However if I move from the results tableview to a detail scene and then navigate back to the main view controller, the keyboard appears off-screen again.
Question
Is there a method I can use to intercept the misplaced keyboard so that it displays in the default location?
NB: Along these lines, I have created a NSDictionary property to hold the initial userInfo values with the correct keyboard placement. I am not sure how to reassign these values to get the keyboard to return to it's original placement.
BTW - This seems a bit of a hack to get the keyboard fixed due to a bug in IB, is there some other way that I can try to remedy the situation?
Thanks in advance for any feedback!
Solution
This was such an obscure issue that I'm sharing the solution to save the next person some effort. Like most programming issues, it turns out this one was self-inflicted. In my original iteration of this project I had turned off rotational support as I am learning auto-layout and I wanted to ease into the transition from Springs and Struts. Somehow between the start of the project and the code release I ended up with this bit of code in the Main Scenes' View Controller.
//BAD
- (NSUInteger) supportedInterfaceOrientations
{
return !UIInterfaceOrientationPortraitUpsideDown;
}
instead of returning a valid enumeration like...
//OK
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
Hi how can i get what button is clicked on keyboard.I need to have some kind of listener which get what button is clicked on uiKeyboard.
thanks
I finally made it, but i think it is one of the ugliest way, but i share my discovery to you.
1.)i made the viewController uitextviewdelegate , and add text view with 0 height and width
2.)i implement the method
- (void)textViewDidChange:(UITextView *)textView
3.)then i got the value of the last clicked key on keyboard like this
foo = textView.text;
textView.text = #"";
so this is one way but if you know nicer method for this answer my question :)
I have implemented a UISearchDisplayController using Apple's TableSearch sample reference. My list contains just over 10.000 elements, and this makes the filtering too slow to execute it on every character that the user enters. I've managed to restrict to search to when the user click on the search button with the following code.
- (void)searchBarSearchButtonClicked:(UISearchBar*)searchBar
{
[self filterContentForSearchText:[self.searchDisplayController.searchBar text]
scope:[self.searchDisplayController.searchBar selectedScopeButtonIndex]];
[self.searchDisplayController.searchResultsTableView reloadData];
}
- (BOOL)searchDisplayController:(UISearchDisplayController*)controller
shouldReloadTableForSearchString:(NSString*)searchString
{
return NO;
}
Now, my problem is, that as soon as the user enters the first character the dimming of the table view disappears, and I would like to keep it dimmed until the user clicks the Search buton. (Or cancels the search.)
The searchDisplayController is a black box so you don't have any control over when it displays the searchResultsTableView (which in on first key press in the searchBar).
You could display a translucent view over the resultsTableView to give the appearance of the initial dimming provided by the searchDisplayController but the searchResultsTableView will still be visible.
- (BOOL)searchDisplayController:(UISearchDisplayController*)controller
shouldReloadTableForSearchString:(NSString*)searchString
{
// display a translucent view over the searchResultsTableView and
// make sure it's only created on first key press
return NO;
}
The other option is to code your own.