Compare WKInterfaceLabel Text to Another NSString - objective-c

I know there is no getter method for WKInterfaceLabel, but is there another way for me to compare the label text to another string? If this wasn't a watch app and I was using UILabel I could just do this:
if ([self.label.text isEqualToString:someString]) {
}

There's no supported way to get the text, just as you said, however you may want to use the accessibility elements as "option".
Here's the idea:
When self.label text is set (either in code or storyboard) also set the corresponding accessibility label/value. When you need to read/update the label text, just make sure you use the accessibility values instead.
self.label.text = #"foo";
self.label.accessibilityValue = #"foo";
if ([self.label.accessibilityValue isEqualToString:someString]) {
self.label.text = #"bar";
self.label.accessibilityValue = #"bar";
...
}
Plus it's how you would use accessibility anyway so it's legal. There may be other ways to accomplish, but this seems to be the quickest and safest way to do what you want.

Related

NSTextField Autocomplete / Suggestions

Since some days I am trying to code an autocompletion for a NSTextField. The autocompletion should look that way, that when the user clicks on the NSTextfield a list should be displayed under the TextField which possibilities are available. After typing one letter or number the list should refresh with the possibilities.
The suggestions in this list should come from an NSMutableArrayor a NSMutableDictionary
This autocomplete / autosuggestion method should be for a MAC application.
Just adding to #AbcdEfg's answer, to make NSComboBox case-insensitive, you can subclass it and override it's [completedString:] method like this:
- (NSString *) completedString:(NSString *)string {
NSUInteger l = [string length];
if (!!l)
for (NSString *match in [self objectValues])
if ([[match commonPrefixWithString:string options:NSCaseInsensitiveSearch] length] == l)
return [match stringByReplacingCharactersInRange:NSMakeRange(0, l) withString:string];
return nil;
}
You can use NSComboBox for that matter. You also need to set its Autocompletes attribute in IB or [comboBox setCompletes:YES] in code.
Keep in mind that it is case-sensitive.
However if you need it to be done in the exact way that you described, you need to make the list by subclassing NSWindowController and NSTableView and change them to look like a list or menu to show under you NSTextField. Set the NSTextField's delegate and do the search and list update on text changes.
Avoid the NSMenu in this case as it will take away the focus from the text field while you are typing.
Apple addressed it in WWDC 2010 Session 145.
They explained about a text field with suggestions menu and how to get it to work. They also provide the sample codes in their website.
You can find the sample code here.

NSString with fixed length

I want an nsstring object that can only store specified lenght of character in it.
If it exceeds it should get truncated from left. For example if i set lenght to 5, and I enter value as Ileana then it should store leana.
I tried by making a category on nsstring but i am out of ideas :
-(void)setMaximumLength:(NSInteger)length;{
if ([self length]>length) {
NSLog(#"exxed");
}
}
Please suggest what should I do? I hve one thng in my mind I need to observe the string size but how to do in a category, and which notification will be called?
This sounds suspiciously like formatting for display or processing user input or something like that rather than an actual constraint you want to impose on strings in general. In that case, an NSFormatter class or a bit of code in some specific controller property setter would be a good idea.
But if you really want this to be on the string itself, you either need to provide a method like stringByTruncatingToLength: on NSString or you need to switch to using NSMutableString everywhere, because NSStrings cannot be modified at all and thus a setMaximumLength: method would be kind of meaningless.
The mechanism of truncation can be implemented like this:(for a NSString property of a custom class)
-(void)setName:(NSString*)newName
{
if([newName length]> maxLength)
{
newName = [newName substringWithRange:NSMakeRange([newName length] - maxLength, maxLength];
}
_name = newName;
}

Accessing UI Input elements as I would in HTML

I am dumping multiple inputs into a view. They consist of UITextFields UIPickerViews and UIDatePickers.
Each of them have an ID and a Key that need to be saved when the input value is saved. So when the 'Save' button is clicked, I need to loop through and store something like:
{
ID: 'inputid',
Key: 'yearly',
Value: (UITextField value)
}
In HTML, I would just add these values to the input (<input type="text" id="inputid" name="yearly" />) and then loop through each one using $(input).attr('id') etc.
In Objective-C, the only way I can think to do this is to keep a hashtable of this information when I draw the inputs, and then store some kind of identifier against the 'tag' field of the UITextField, then read that by getting all of the inputs from a view and comparing them to the hashtable.
Is this the right way to go about it?? Am I missing something simple here? How would you go about it?
EDIT
To better frame the situation, the number of UITextFields on the page is being pulled from an XML file, therefore I don't know how many UITextFields there will be (so can't assign them to the controller necessarily)
I need something along the lines of:
foreach(var question in ArrayOfQuestions) {
UITextField *textField = [[UITextField alloc] initWithFrame:];
textField.attributes["id"] = question.Id;
textField.attributes["key"] = question.Key;
}
and in the save method
foreach(var textField in UIView) {
textField = (UITextField)textField;
NSString *id = textField.attributes["id"];
NSString *key = textField.attributes["key"];
}
This maybe something I could find in google but can't think of the right search terms and keep coming up empty handed. On the same level, if you can better describe my request please update the title of my question
I think you are actually at the best solution, in regards to the hash table (NSDictionary) of attribute data. It is really a bad design decision to have too much semantic data in the view object itself, as it has nothing to do with the view.
What you need to do concretely in code is the following:
To set up your views & attribute data:
UIView *containerView; // The view that contains your UITextViews.
NSMutableDictionary *attributes; // A dictionary mapping tags to questions.
NSMutableArray *arrayOfQuestions; // The questions that you've parsed from a file or whatever.
// ...
// Each "question" would be of the form #{ #"id" : ____, #"key" : ____ }
for (NSDictionary *question in arrayOfQuestions) {
UITextField *textField = [[[UITextField alloc] initWithFrame:aFrame] autorelease];
[containerView addSubview:textField];
textField.tag = getATag(); // However you want to tag them.
// Fancy new objective-C container/object-literal syntax :)
attributes[#(textField.tag)] = question;
}
Then for your "save" method:
for (UIView *childView in containerView.subviews) {
if ([childView isKindOfClass:[UITextView class]]) {
// We know the class and can thus safely typecast the UIView.
UITextField *textField = (UITextField *)childView;
NSDictionary *aQuestion = attributes[#(textView.tag)];
// Now you can access the id and key properties of the question.
// ... Whatever else you want to do.
}
}
The enumerated loop over the subviews is I think the big thing you were looking for here. It is very similar to the way that you would do it in jQuery with selectors.
If you make each of the elements a property of the view controller, you can access them directly from anywhere and get the current value.
So in the method attached to the save button, you can get the current string value of a UITextField like this, for example:
NSString *currentTextFieldString = self.someTextField.text;

How do I receive the current value of a slider in code?

I am (attempting) developing my first application in Xcode using cocoa framework.
I have a slider which min value is 10 and max is 50. This is to select max search results.
I have linked a label on my user interface to display the value of the slider and when it is moved, it updates the label on the user interface.
However, I am trying to join around 4 strings to create my final URL one of them is the value of said label.
I am trying to read the value of the label on the interface for use in creating the finished URL
NSString *startofURL = #"http://starturl.com/?q=";
NSString *searchTerm = whatToSearch;
NSString *middleofURL = "&max-results=";
NSString *resultsStr = labelMaxResults.stringValue; //Problem here ??
I have 2 questions; firstly, How do I go about retrieving the value of my slider via code instead of trying to get it from the linked label, as I think this is my problem.
secondly, I have read up on joining and appending strings, however I am a little confused on which is the best method to use in order to join up the 4 strings into one long URL.
NSSlider * slider = [[NSSlider alloc] init];
[slider setMinValue:50];
[slider setMaxValue:150];
int sliderValue = [slider intValue];
this doesn't put your slider on screen, but assume you made it in IB, ignore the first line, you can set your min max and get the value.
you can make an action like
-(IBAction)sliderMoved:(id)sender
then bind that to the slider, if you set the slider to continuous you will get updates every time that it moves other wise just when you let go of the slider
-(IBAction)sliderMoved:(id)sender
{
sliderValue = [slider intValue];
[self doSomethingElseNow];
}
For the first part of your question, it depends which OS you are using as to which process to use.
If you are using OS X, the best way to get a value for your slider is to create a binding in IB for your slider. To do this, click on the slider in IB and go to the bindings section. In the Value section, click on Value and select the class you wish to use the value in as your Bind To class (I'm going to use MyClass for this example). Then for the model key path, assign it to some value of your choice. For the purpose of this, I'll just call it sliderValue.
Then in MyClass.h, you must set up the following:
#interface MyClass : <your class type> {
int sliderValue;
}
#property (readwrite, assign) int sliderValue;
In MyClass.m, you'll need to synthesize the value.
#synthesize sliderValue;
At this point, you should be able to get the value of your slider at any point in your code by calling [self sliderValue].
If you are, however, using iOS, then all you have to do is call the value property from your slider. So if you have the a UISlider *mySlider, all you have to do is call mySlider.value to get the current value of your slider.
For your second question, you can go about this two ways. If you want to append the strings, simply follow the format:
NSString *appendedString = #"";
appendedString = [appendedString stringByAppendingString:string1];
and so on until you have all your strings into your URL.
In your case, I would personally set up the entire URL string as a stringWithFormat:
NSString *urlString = [NSString stringWithFormat:#"http://www.starturl.com/%#%#%#", whatToSearch, middleOfURL, resultsStr];
Insert the values you want into the URL that way by setting up whatToSearch, etc., to the values you want. This way, you don't have to worry about appending everything together
Your code should look like this:
NSString *urlString = [NSString stringWithFormat:#"http://starturl.com/?q=%#&max-results=%f", whatToSearch, [slider floatValue]];
EDIT: Corrected my answer. For UISlider it should be value property. For NSSlider you should use - floatValue method

Use an If statement with the button name in Objective-C (Cocoa/iPhone SDK)

I have to implement a small feature in an iPhone app and was wondering if there was a way to do use an if statement where the condition is the string of a button.
Here’s a sample of the code in question:
- (IBAction)someMethod:(id)sender{
UIButton *button = (UIButton *)sender;
if ( button.titleLabel.text == “SomeText” )
{
//do something
}
else
{
// some other thing
}
Now I can’t make it work, because I think I’m using the wrong code in button.titleLabel.text. I’ve even tried #“SomeText”), but I always end up in //some other thing.
What am I doing wrong?
Thanks.
What you're currently doing is comparing two pointers to objects, the objects button.titleLabel.text and #"SomeText". As both point to different places in the memory, the comparison will return NO.
If you want to compare the values of both NSString objects, however, you can use [button.titleLabel.text isEqualToString:#"SomeText"].
Also note that "SomeText" is not the same as #"SomeText"! The first is a regular C string, where the last one is a Cocoa NSString object.