pausing objective-c runtime loop for user input - objective-c

I have this code:
while (!found) {
char letterGuess=(char)([[[wordList letterRank:lengthOfWord]objectAtIndex:yescount]intValue]+97);
NSString *stringLetter=[NSString stringWithFormat:#"%c",letterGuess];
if ([prevGuess count]<=0) {
alreadyGuessed=NO;
}else {
if ([prevGuess containsObject:stringLetter]) {
alreadyGuessed=YES;
yescount++;
}else{
alreadyGuessed=NO;
}
}
if (!alreadyGuessed) {
[prevGuess addObject:stringLetter];
[self drawYesNo];
NSLog(#"%c",letterGuess);
}
if (userAnswer) {
}else {
[self noGuess:letterGuess];
}
if ([wordList count]<=1) {
NSLog(#"word found");
found=YES;
}
}
basically, it takes a letter from a sorted array, checks it against another array containing all the previous letters that were entered, and if it is not in that array, it will call [self drawYesNo], which basically sets up and draws a yes and a no UIButton, and based on what the user presses, changes the 'userAnswer' variable.
My problem is that this loop executes so quickly that the objectAtIndex quickly exceeds the bounds of the array, and throws an error. I need some way to pause during the [drawYesNo] method, and allow the user to actually make a decision.
I know there are answers to similar questions on StackOverflow, but I just can't make heads or tails of them. Can someone please explain this for a very new OO programmer?

I can't really figure out all the logic of your code, but it sounds like you need to refactor it into different methods. Instead of having the code in a while loop, you should have one method that does most (all? I can't tell) of what you posted (without the while loop). You call this once when your app starts, then after the user clicks a button -- in the button's action method you change the value of userAnswer, and then call that method again. This keeps going until some condition is met in your button method that would cause it to stop.

Related

Office UI Fabric - PeoplePicker: Cannot get createGenericItem to work

Perhaps it's just a misunderstanding on my side, but I thought the callback for createGenericItem in the PeoplePicker (https://developer.microsoft.com/en-us/fabric#/components/peoplepicker) was used to handle input, that cannot be matched to any of the available items, and then give the possibility to create an adhoc item for this. But, whatever I tried, the callback is never called.
I made a simple pen here for the issue: https://codepen.io/anon/pen/daGPWe?editors=0010
In the example, there are two items, Peter and Maria. If you type something different (and hit enter, tab, space, whatever) I'd expect the createGenericItem callback to be called, but it isn't.
What am I doing wrong? Or is there a misunderstanding of the purpose of this callback? I'm unable to find an example anywhere.
Regarding
but I thought the callback for createGenericItem in the PeoplePicker
(https://developer.microsoft.com/en-us/fabric#/components/peoplepicker)
was used to handle input
that's correct. In order to trigger IBasePickerProps.createGenericItem function, IBasePickerProps.onValidateInput function needs to be provided with ValidationState.valid as a return value, for example:
<NormalPeoplePicker
createGenericItem={this.createGenericItem}
onValidateInput={this.handleValidateInput}
selectedItems={this.state.selectedItems}
onResolveSuggestions={this.handleResolveSuggestions}
onChange={this.handleChange}
/>
private handleValidateInput(input: string) {
return ValidationState.valid;
}
private createGenericItem(input: string, validationState: ValidationState) {
return { text: "Unknown person", state: validationState };
}
This demo demonstrates it, once tab or enter key is clicked and value cannot be resolved to any of the available items, Unknown person item is getting displayed

Reactivecocoa two-way binding of UISlider to a value, update UI only when user isn't touching it

I have a UISlider which shows playback progress through a song and allows seeking within the song.
Using RAC it's very easy to obtain a two-way binding between a UISlider's value and a viewModel's value:
RACChannelTo(self, slider.value) = RACChannelTo(viewModel, progress);
However problems arise while the user is interacting with the slider:
with continuous updates, while the user is moving the slider updates are constantly being sent to the VM leading to jittery sound;
without continuous updates, the jittery sound issue is no more, but the VM is constantly updating its progress value leading to the UI jumping to the latest value from under the user's finger.
I've tried the [slider rac_newValueChannelWithNilValue:#0] approach with same results. My current solution works, but is shamefully complex:
// Sadly the rac_signalForControlEvents doesn't send the event that triggered it so two signals are needed
RACSignal *touchDown = [self.slider rac_signalForControlEvents:UIControlEventTouchDown];
RACSignal *touchUp = [self.slider rac_signalForControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
RACSignal *isTouched = [[[touchDown map:^id(id value) {
return #(YES);
}] merge:[touchUp map:^id(id value) {
return #(NO);
}]] startWith:#(NO)]; // Needs a startWith because combineLatestWith doesn't send signals until it has at least one value from each component
[[RACObserve(viewModel, progress) combineLatestWith:isTouched] subscribeNext:^(RACTuple *tuple) {
RACTupleUnpack(NSNumber * progress, NSNumber * isTouched) = tuple;
// Update the slider value only if the user isn't touching it
if (!isTouched.boolValue) {
weakSelf.slider.value = progress.floatValue;
}
}];
// Send the value only when user stops interacting
[[touchUp map:^id(UISlider *slider) {
return #(slider.value);
}] subscribeNext:^(id x) {
weakSelf.viewModel.progress = [x floatValue];
}];
Is there a better way of achieving this?
Have you tried using throttle to decrease the number of values sent from the slider?

Durandal - Correct way to disable .canDeactivate for 'Success' operations?

I have an edit page (in a DurandalJS single page app), where I use the .canDeactivate lifecycle method to check if there are any changes to the record, and optionally prompt them for confirmation before leaving the page.
I also have a 'Save' and 'View History' button. Is the correct thing to do to override the .canDeactivate method before calling router.navigate, to stop the modal popup invoking?
E.g.: As here:
self.onSave = function() {
self.repository.updateItem(self.model).done(function() {
self.canDeactivate = null; // Is this the correct way to do this?
router.navigate("#/home");
}
}
As this .canDeactivate will otherwise get called:
self.canDeactivate = function() {
if (!self.model.hasChanges()) {
return true;
}
return app.ShowMessage("Unsaved data will be lost", "Are you sure you wish to exit?", ["Yes", "No"]).done(function(result) {
return result !== "No";
}
};
Why dont you just set
self.model.hasChanges(false)
in your updateItem callback?
Then when your canDeactivate is called, it will return true.
Also you seem to have an error in your ShowMessage callback. I think you mean to do:
return result != "No";
I don't think the way Durandal decides whether to attempt to call a canDeactivate function is fully defined, other than the fact that if it's not in the view model, it won't try. Hence, even if it works as is, a future version of the framework could change its check to something like if (canDeactivate in viewModel) viewModel.canDeactivate(...); without further tests, and your code would break.
This is unlikely, but if you want to worry about it, you should thus delete self.canDeactivate instead of assigning it the null value.
Quote from the documentation:
To participate in the lifecycle, implement any (or none) of the
functions below on the object that you set the activator to (...)
Current implementation (activator.js, L126, 1eecbc2d3f84dc42eb7304bde761d88f300d8951):
if (item && item.canDeactivate) {
So it only checks if it's truthy (which would indicate using null works fine currently, too).
If you want to discuss the pattern, I don't see anything wrong with it, as long as it makes sense to you and everyone who should read the code.
You're not supposed to be activating and deactivating views programmatically in any critical path, so performance should be irrelevant either way (flag on view model or deletion of canDeactivate).

Cant handle it (jQuery hanlder understanding needed)

I'm embarrassed to even ask BUT could someone help me understand what a "handler" is. I am new to jQuery and the API constantly has references similar to the following:
toggle( handler(eventObject), handler(eventObject), [ handler(eventObject) ] )
I scratch my head and say to myself "what the hell is a handler". Then I check my 2 jquery books and don't really see anything specific there. I get what an event handler does, it handles an event. But the word handler in the above context confuses me including "eventObject". I tried to google it but could not really find a really clear definition of what exactly a handler is as it relates to jquery. Thanks for your help =]
Handlers are any functions that you write to handle events. For e.g. in
$(document).ready(function() {
//......
});
the handler is
function() {
//.......
}
Think of a handler as a callback for whatever operation is being invoked. In the case of handler(eventObject) it means that the method with that parameter can accept a function being passed to it and that function will be called at some specific point in time before, during, or after the execution of the method receiving it (as indicated by the parameter specification) and it will be passed a value called eventObject which can be anything, but is most likely the target of the given event your callback is being issued for.
Here's an example:
function MyCallback(eventObject) {
alert(jQuery(eventObject).attr('id') + ' toggled'));
}
jQuery("#myBtn").click(function() {
jQuery("#myObj").toggle("fast", function(eventObject) { MyCallback(eventObject); });
});
With the above code, when #myBtn is clicked the element #myObj will be toggled (fast) and as soon as the toggle animation completes MyCallback will be called and passed #myObj which will cause an alert to appear saying, "myObj toggled".
This is the function which will handle the event. To expand, in the case of toggle, ON calls the first function (with the eventObject) and OFF calls the second function. eventObject will hold different info depending on events, like coordinates of the mouse.

iPhone, differentiate between multiple controls?

What is the best way when setting up a UI for the iPhone to differentiate between multiple items of the same type (i.e. 2 sliders) currently I am assigning the controls unique "tags" and then querying them in Xcode. Is this the way to go or am I missing something else?
-(IBAction)switchChanged:(UISwitch*)senderSwitch {
if([senderSwitch tag] == 1) {
NSLog(#"SwitchChanged: Engines");
}
...
gary
Hey Gary! I usually choose similar approach, though I prefer using integer constants instead of 'raw' numbers. Here's an example:
const int VIEW_TAG_A_SWITCH = 1;
const int VIEW_TAG_OTHER_SWITCH = 2;
- (IBAction)switchChanged:(UISwitch*)senderSwitch {
switch (senderSwitch.tag) {
case VIEW_TAG_A_SWITCH:
// do something
break;
case VIEW_TAG_OTHER_SWITCH:
// do something else
break;
}
}
This makes code more informational and help you to deal with situations when you need to change the UIView tag value for some reason (this way you only change it once in your nib and once in your code).
It's also very handy to use enums when you need to work with a group of controls. Here's a dummy single selection group of buttons example (something similar to what <input type="option" />):
enum GenderOptionButtons {
kMaleGenderOptionButton = 10,
kFemaleGenderOptionButton,
kUndefinedGenderOptionButton,
NUM_GENDER_OPTION_BUTTONS
}
- (IBAction)buttonDidTouchUpInside:(UIButton *)senderButton {
for (int i = kMaleGenderOptionButton; i < NUM_GENDER_OPTION_BUTTONS; i ++) {
[(UIButton *)[self.view viewWithTag:i] setSelected:NO];
}
senderButton.selected = YES;
}
If you don't own direct reference (i.e. IBOutlet) to controls, then the "tag" approach is ok.
One advantage of this approach is that you can have different kind of controls calling the same action method. One major drawback of this approach is you have to keep in sync the tags between IB and XCode.