Resetting the search query string in UISearchController programmatically - objective-c

I am failing to reset/substitute the search query string programmatically. I was trying to modify the UISearchBar query string from within the UISearchControllerDelegate.
I am using dictation input.
When the command "delete" is said, the searchController.searchBar.text should be set back to #"". The speech detection should continue as normal with the empty string.
The query string does get reset to #"", but the speech detection stops.
How can I reset search query string in UISearchController programmatically and still be able to continue the input using speech?
- (void)updateSearchResultsForSearchController:(nonnull UISearchController *)searchController {
NSString *searchQuery = self.searchController.searchBar.text;
// Deletion command
if ([self.searchController.searchBar.text hasSuffix:#"delete"]) {
// Things that I've tried that don't work
//[self.searchController.searchBar setText:#""];
//self.searchController = [self.searchController init];
//self.searchController.searchBar.text = #"";
searchQuery = #"";
}
}

This feature is yet not available in iOS. As soon as you try to clear the text in searchBar's TextField, it change the keyboard mode to keypad input.
So, the conclusion is, you can only provide the input to the textField using the dictation but can't clear it. User has to manually do the process to change again to Dictation Input.
Hope it helps.

Related

plist.Info so that app takes icon based on command line arguments

I have a .app. I want to edit the plist.Info such that if a command line argument of -P "main" is in the path it will use another of the icons in my resources folder. And if user right clicked and said "keep in dock" it will keep in dock with command line arguments, so on next click it will launch with same command line arguments.
Is this possible?
Worst cast scenario: Any objective-c way to check the path to see if any command line arguments there? Then I'll run setApplicationIconImage programtically (worst case meaning if the above is not possible) (and then ill also have to programtically fetch the miniaturized windows with [NSWindow miniwindowImage] and draw the mini icon on their msyelf and also listen to future notifications of NSWindowWillMiniaturizeNotification and do the draw when that notification fires, so this is worst case scenario)
I am not sure I follow you fully.
But I don't think you need to edit the plist.Info and I think it is not good to do that any way.
I would just to write to the apps preference file with CFPreferencesSetValue and change an entry which determines if the app changes it's icon.
Call made from you argument check:
[self changIcon:(CFBooleanRef)false];
-(void) changIcon:(CFBooleanRef)prefValue
{
CFStringRef appID = CFSTR("com.yourApp.BundleID");
CFStringRef Key = CFSTR("swapIcon");
CFBooleanRef Value = prefValue ;// kCFBooleanTrue;//or kCFBooleanFalse
// Set up the preference.
CFPreferencesSetValue(Key,
Value,
appID,
kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
// Write out the preference data.
CFPreferencesSynchronize(appID,
kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
}
Change the icon
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
BOOL swapIcon = [defaults boolForKey:#"swapIcon"];
if (swapIcon ) {
NSImage * b1Image = [NSImage imageNamed:#"bl1"];
[NSApp setApplicationIconImage:b1Image];
}else {
[NSApp setApplicationIconImage:nil];//--Nil will make the app use thenormal icon
}
For a better answer you would need to explain a bit more clearly.

Password visible when Typing then ***

I would like to make my password field visible when typing and when finished (change to another field) convert it to *.
As my app has only one password field (no confirmation) its easy the user mistype.
How can I do that?
try this,
UITextField *txtPassword = [[UITextField alloc] init];
txtPassword.secureTextEntry =YES;
You can follow these steps:
set pwdTextField.delegate = self
implement textfieldDidEndEditing delegate
Do nothing special while user input text
Now in textfieldDidEndEditing store your current password in a variable (for future use)
Replace pwdTextField.text = noOfStarsEqualToLenghtOfString
That's it. Happy coding.
Firstly I suggest to use the secure textfield. Otherwise try this:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == txtPassword)
{
//Check total no of characters in that textfield & replace all with *.
}
return YES;
}
And on confirm button clicked(register/login), check the password with the password which you added before replacing with *. Consider * just for displaying purpose.

Setting NSMatrix selection programmatically causing mutex lock when trying to later get selected cell

Overview
I'm seeing a strange issue in a Mac OS X Cocoa app I'm developing w/Xcode 4.3.2 and testing on Mac OS X 10.7.5 (targeting Mac OS X 10.6): I have a basic NSMatrix radio group in my main NIB that has one outlet and one action in my main controller, but is also used in two other methods (also in the main controller). The action saves the selected tag to NSUserDefaults & enables/disables an NSTextField based on which is selected, one method is a preferences loader and so selects a cell by tag upon load, and the other method looks up it's selected tag for other logic (code samples below).
Basic stuff, but in one case (when only having selected a cell in the NSMatrix programmatically, not via clicking a radio button in the GUI), the app PWODs in a mutex lock.
The Code & Functionality
I've renamed variables & methods below, but have not changed any of the other structure of the code. passwordRadioGroup is the NSMatrix* IBOutlet.
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
// get logging up and running
[self initLogging];
// load various prefs
// ...
[self loadPasswordSettings];
}
- (void)loadPasswordSettings {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// load password settings from our prefs
NSNumber *passwordTypeTag = [defaults objectForKey:kPasswordTypeDefaultKey];
if ( passwordTypeTag != nil ) {
[passwordRadioGroup selectCellWithTag:[passwordTypeTag intValue]];
} else {
[passwordRadioGroup selectCellWithTag:kPasswordTypeRadioRandomTag];
}
[self selectPasswordType:passwordRadioGroup];
// ...
}
- (IBAction)selectPasswordType:(NSMatrix *)sender {
NSInteger tag = [[sender selectedCell] tag];
switch ( tag ) {
case kPasswordTypeRadioRandomTag:
// disable the password text field
[passwordField setEnabled:NO];
break;
case kPasswordTypeRadioManualTag:
// enable the password text field
[passwordField setEnabled:YES];
break;
}
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:tag] forKey:kPasswordTypeDefaultKey];
}
- (NSString *)generateUserPassword {
NSString *password;
// which type of password should we be generating (random or from a specifed one)?
NSInteger tag = [[passwordRadioGroup selectedCell] tag];
switch ( tag ) {
// manual password
case kPasswordTypeRadioManualTag:
password = [passwordField stringValue];
break;
// random password
case kPasswordTypeRadioRandomTag:
// password = randomly generated password;
break;
}
return password;
}
When the app is launched, my main controller is sent a applicationDidFinishLaunching message which then sends the loadPasswordSettings message to itself. loadPasswordSettings then sends [[passwordRadioGroup selectedCell] tag] and sends [passwordRadioGroup selectCellWithTag:]. This works correctly and the correct radio button is selected in the GUI. It finally calls [self selectPasswordType:passwordRadioGroup (which also successfully calls [[passwordRadioGroup selectedCell] tag]) and appropriately enables/disables the text field and writes the tag back out to NSUserDefaults (usually, but not always redundant).
You can select any of the radio buttons, which sends a selectPasswordType: message to my main controller (passing it the instance of passwordRadioGroup; I've verified the memory address in the debugger and can inspect its ivars). This successfully calls [[passwordRadioGroup selectedCell] tag] and saves the tag to NSUserDefaults.
You can do the above two as many times as you like without issue. Quitting & relaunching correctly restores the radio buttons to the state you left them last, so it's definitely correctly getting the selected tag, storing it in NSUser defaults, retrieving it from NSUserDefaults, and setting the selected cell by tag on the NSMatrix.
Here's where it gets screwy:
There's another button that, when clicked, does a bunch of other work and ultimately then sends the generateUserPassword message to itself to generate a password (again, this is all in the main controller and running in the main thread). What's the first thing that it does? Calls [[passwordRadioGroup selectedCell] tag]. Fine, you can safely do that as much as you want, as illustrated above, right?
If you select one of the radio buttons, therefore changing the selected cell via the GUI and sending the selectPasswordType: message to my main controller again, yes. You will encounter no issues (although, I admit it seems a bit slow and PWODs for a second).
If you do not click on the NSMatrix after launch (so not forcing the selection/action again from the GUI), that [[passwordRadioGroup selectedCell] tag] call in generateUserPassword will immediately PWOD. If I hit the pause button in Xcode's debugger to see where it's at, it's always in psych_mutexwait (called from class_lookupMethodAndLoadCache) in the main thread. If selectPasswordType: weren't called programmatically and able to run [[passwordRadioGroup selectedCell] tag] without issue, I'd have at least some sanity left.
Help!
To reiterate, I've followed this through in the debugger and can verify that the memory address & ivars confirm that passwordRadioGroup is not being changed out from under me, nor is it being deallocated (I've tried with & without "Zombie Objects" enabled). The only references to passwordRadioGroup in my main controller are those seen above. Googling for all sorts of NSMatrix/radio/selectCellWithTag/selectedCell/selectedTag/class_lookupMethodAndLoadCache/mutex terms/combinations has not been fruitful.
Any solutions, troubleshooting suggestions, or thoughts would be greatly appreciated. Slaps for stupidity also welcome, if deserved.

Need a view that acts like a log view

I need to implement a view that acts as a log view, so that when you push a message into it, the message would push other messages upwards.
Is there anything like that for iOS?
You can easily implement that using standard UITableView:
Each cell will be responsible for displaying 1 log message
Add new cell to the end of the table when new message arrive
Scroll table to the bottom after cell is added (using scrollToRowAtIndexPath:atScrollPosition:animated: method with UITableViewScrollPositionBottom position parameter)
That means you'll need to store your log messages in array, but if you're going to display them you need to store messages anyway
#Vladimir's answer is probably the way to go, but just for the sake of seeing some additional options, here's an example using a UITextView:
- (IBAction)addNewLog:(UIButton *)sender {
NSString *myInputText = #"some new text from string";
NSString *temp = myTextView.text;
[myTextView setText:[temp stringByAppendingString:[NSString stringWithFormat:#"\n%#: %#",[NSDate date],myInputText]]];
[myTextView setContentOffset:CGPointMake(0, myTextView.contentSize.height - myTextView.frame.size.height) animated:NO];
}
Then if you wanted to separate the text in the text view into objects in an array:
NSArray *myAwesomeArray = [myTextView.text componentsSeparatedByString:#"\n"];
Mind you, the above would break if the "myInputText" string ever contained a line break.

Xcode Like log with NSTextView

I'm trying to set up a NSTextView like the console in Xcode (or pretty much any other IDE available). That being the user cannot edit the NSTextView, however they can put in a character when appropriate, I'm trying to set up that same functionality. No clue how to go about it. Any ideas?
You could simply make an action that appends a formatted string containing a line break, a time stamp, and your desired text to the text view. Here's an example:
- (void)addToLog:(NSString *)input
{
[[self.myTextView textStorage] appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:#"\n%#: %#",[NSDate date],input]]];
}
So then instead of using NSLog(#"some text"); you could call [self addToLog:#"some text"]; and it would be added to a new line in your text view.