How can I pause execution within a method until the user sends a "Did End on Exit" (presses the "Next" button on the keyboard? - iphone

This is what I have:
while(wordList){ //wordlist is instance of NSArray containing NSStrings
word.text = [wordList objectAtIndex:x]; //word is instance of UILabel
//LOOKING TO PLACE WAIT CODE HERE TO WAIT FOR "DID END ON EXIT"
input = inputBox.text; //input is instance of UITextField
[self compare:input andb:word.text]; //compare is an instance method to compare the two strings
x++;
}
I'm a beginner, if any of you could help me, that would be fantastic.
Best...
SL

Is this what you are looking for?:
[yourTextField addTarget:self
action:#selector(yourMethod:)
forControlEvents:UIControlEventEditingDidEndOnExit];
Edit:
Why don't you just break the while loop and call a separate method when the user hits next? No need to pause and trigger some other method.

The approach you're asking about won't work. If your app were to pause execution in the middle of a method, what would cause it to unpause?
The user is not going to be entering text in the middle of your loop -- that would have to have already done that before the loop starts to execute. Trigger the method that contains the loop as #Imirak suggested, or from some other user interaction, for example a button press. That way you'll know that the user has already entered the text, and the code you've written should work as expected.
One note though: the code you've shown doesn't check the return value from your compare:andb: method. You haven't really provided enough information about what you expect the method to do to do to be sure whether that makes sense or not.
Also, your loop control logic is incorrect -- as written it's either going to be an infinite loop or it will never be entered, depending on whether wordList is nil. Consider using fast enumeration syntax instead of writing a while loop, for example:
for (UILabel *currLabel in wordList)
{
// It appears as though this may be the comparison you want to do
// but there's not enough context in your question to be sure.
//
if ([inputBox.text isEqualToString:currLabel.text])
{
// Do something here. Again, it's not clear what you're trying to do.
}
}

Related

unexpected frame appears onto another frame after an event

I'm using a character application. In the first page, there is a frame f-selection where the search fields are entered. When I search for something and open some other frames in that search, then I press F10 which is for opening another frame, the new frame opens but f-selection also appears on it. I'm suspecting this code makes it pop up again:
else assign ll-lgst-key1:SENSITIVE in frame f-selection = TRUE
ll-lgst-key2:SENSITIVE in frame f-selection = FALSE
because when I comment these lines, the frame doesn't pop up. But then I can't use these fields at the first frame where I should, too. I don't know why this code is called again; but is there anything else I can do to fix this issue? I tried to write hide frame f-selection everywhere possible but it doesn't work.
That snippet of code is making "key1" of your frame sensitive. In order to be sensitive it needs to pop up...
So the issue is why is that block of code executing? You say "I don't know why this code is called again". Neither will anyone else because you have shared such a tiny little bit of the overall code. Apparently the flow of control is taking you through that block so you should work on understanding why that is. You might try using the debugger to step through the code execution or you could insert some old fashioned MESSAGE statements to get to the bottom of it.
If you want to kludge around the problem you could wrap that bit of code in conditional logic. Define and set a variable that determines the desired state of the f-selection frame and use that to control the sensitivity logic:
define variable f-shouldBeVisible as logical no-undo.
if .... then
f-shouldBeVisible = yes.
else
f-shouldBeVisible = no.
...
else
do:
if f-shouldBeVisible then
assign ll-lgst-key1:SENSITIVE in frame f-selection = TRUE
ll-lgst-key2:SENSITIVE in frame f-selection = FALSE
.
end.
Of course that looks kind of silly -- but it is just an example with grossly over-simplified logic.
OTOH if you know enough to set the variable you ought to be able to figure out why the ELSE branch is executing. But maybe it is a useful first step.

Unit test in IOS

I have a UIbutton in my app. When I click the button, it removes the last object in a NSMutableArray. For this, I want to write unit tests.Please any one give me your suggestion.
I use this code for knowing when a click on the UIButton was performed:
[viewControllerObject.backButton1 sendActionsForControlEvents:UIControlEventTouchUpInside];
Thanks,
Ricky.
At a "unit" level there are two things you're testing:
does tapping the button send the action method?
does the action method remove the last object from an array?
Ignore the first one, that's Apple's problem (or charitably it's an integration test). The second is straightforward if you think about the Assemble, Act, Assert process:
Assemble: build your view controller and its content array.
Act: call the action method.
Assert: check that the last object was removed.
-(void)testRemovalOfLastObjectOnButtonAction
{
//... build and populate the view controller
id lastObject = [array lastObject];
[viewController buttonTapped: sender];
STAssertFalse([array containsObject: lastObject], #"Object %# should be removed", lastObject);
}
Note I test explicitly whether the last object was removed, not whether the count was decremented: that could happen if any object were removed.
You can do this in several different ways. A suggestion would be to watch this great tutorial
The video explains how to unit test in UIKit.
XCode has native support for Unit Tests. If you start a new project, look for the check mark that says 'Include Unit Test'. If you use that, you will have a folder called <project_name>Tests. Open the .m file in there, and you'll see a - (void)testExample method where you can put your tests.
You can use a number of functions to test, like STAssertTrue and STAssertNotNil. Check out the Apple docs here: https://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/UnitTesting/03-Writing_Test_Case_Methods/writing_tests.html#//apple_ref/doc/uid/TP40002143-CH4-SW1
In your case, you could probably do something like this:
NSInteger arrayCount = mArray.count;
[yourInstance performButtonAction];
STAssertEquals(arrayCount -1, mArray.count);

Messagebox.show fires twice after button click (MVVM)

I am using Galasoft MVVMLight. I have a button bound to a command which sends a message to the view to display a messagebox asking for confirmation. If I click either the Yes or No on the messagebox it performs the necessary actions then shows up again. However if I step through the program instead I only get the messagebox once. Is this a bug or is something else going on?
EDIT: I modified the messagebox.show line by adding an Icon and default result and now I can't reproduce this behavior... I'm stumped... if it happens again I'll try a counter like airplaneman19 suggested.
Try tracking the amount of times the MessageBox shows up with an integer, like so:
int counter = 0;
if(counter == 0){
MessageBox.Show();
counter++;
}
else if (counter == 1)
/*Do something that won't alter the program just to escape the if....else statement
like "x++";
I had a similar problem once, I mean, with MessageBox firing twice. It was due to focus changes, and ListView in WinForms fired another selection changed event when running the app; but when debugging - some focus change was missing, and there was no bug :)
I hope this atleast gives you some ideas...

When are a methods GUI operations actually carried out?

I am working on a web-services data processing app and I am trying to make the app run as quickly as possible. When a certain 3 finger pan gesture is performed, I call a method that sends updated information off to the server to get a new batch of images to update the existing ones with.
So lets say there are 15 images in an array, I filter through them with a 2 finger gesture, and then if I want to change something about them, I can do the 3 finger gesture, and I get that same set back, just tweaked a bit (contrast/brightness, etc.).
Is what I want though is to be able to update the imageView that is displaying the images after the first image has been retrieved, so as to give the user a feel for what the rest in the series are going to look like. But no matter what I try, and no matter how many different threads I try and implement, I can't get the imageView to update before the entire download is complete. Once the batch download is done (which is handled on a separate thread) the imageView updates with the new images and everything is great.
The first step in the process is this:
if(UIGestureRecognizerStateEnded == [recognize state]){
[self preDownload:windowCounter Level:levelCounter ForPane:tagNumber];// Where this method is what gets the first image, and tries to set it to the imageView
[self downloadAllImagesWithWL:windowCounter Level:levelCounter ForPane:tagNumber]; //And this method goes and gets all the rest of the images
}
This is my preDownload method:
-(void)preDownload:(int)window Level:(int)level ForPane:(int) pane{
int guidIndex = [[globalGuids objectAtIndex:pane] intValue];
UIImage *img = [DATA_CONNECTION getImageWithSeriesGUID:[guids objectAtIndex:guidIndex] ImageID:counter Window:window Level:level];
if(pane==0){
NSLog(#"0");
[imageView3 setImage:img];
}else if(pane==1){
NSLog(#"1");
[imageView31 setImage:img];
}else if(pane==2){
NSLog(#"2");
[imageView32 setImage:img];
}else if(pane==3){
NSLog(#"3");
[imageView33 setImage:img];
}
}
So by separating this out into two different methods (there are no threads being implemented at this point, these methods are being called before all that) I was thinking that after the preDownload method completed, that the imageView would update, and then control would continue on down into the downloadAllImagesWithWL method, but that doesn't appear to be the case.
Am I missing something simple here? What can I do to update my GUI elements before that second method is through running?
You are right. However the viewn won't refresh until your code reaches runloop. You can do 2 things:
Make your downloadAllImagesWithWL method async, so it will return after you called it, your main thread reaches runloop, gui updates, and the download method will tell your logic through a callback when its done.
OR
A simplier hackier (and bad) solution would be to run runloop for some time before you call your download method. Something like this: [[NSRunloop currentRunLoop] runUnitlDate: [Date dateWithTimeIntervalSinceNow: 0.1]]; It will run runloop for 0.1 second.
When the image is set, the image view will mark itself as needing display. The actual display won't occur until the beginning of the next run loop. In OS X, you can use -display to draw the view immediately, but I don't think Apple created a public method to do this on iOS. However, if the next method simply creates the background thread, then it will return quickly and the display update will probably occur before the thread finishes.

Signal fires twice from gtkmm popup list

It's been a while since I used GTK+, and the last time I did was in C, not using gtkmm and C++ as I am now. Anyway, I have what I think should be an easy problem to solve:
I have a pop-up menu consisting of a list of radio buttons, and when I click one of them I want some action to occur. The code goes like this:
Gtk::RadioMenuItem::Group group;
for ( size_t i = 1; i < LH_MAX; ++i )
{
Gtk::RadioMenuItem* pItem = new Gtk::RadioMenuItem( group, names[i], names[i] );
pItem->set_name( names[i] );
pItem->signal_activate().connect( sigc::mem_fun(*this, &MyClass::on_item_activated) );
pItem->show();
m_Menu.append( *Gtk::manage(pItem) );
}
The only problem I see is that MyClass::on_item_activated gets called twice when a previously-unselected radio button is chosen from the menu. It's called only once when the already-selected radio button is clicked.
I'm guessing that the first firing is to say "something is no longer activate," and the second is for the new radio button activation. Whether I'm right or wrong, the question is the same: how best can I have my handler only take action once per click? Either I need the handler to get called only once, or I need something to check from inside it to know if the callback is a "duplicate" or not.
You could use sigc::bind to supply the item as a argument to the callback function.
pItem->signal_activate().sigc::bind(sigc::mem_fun(*this,&MyClass::on_item_activated),pItem));
Then you can use item->get_active() in the callback to respond to activations only.
void MyClass::on_item_activated(Gtk::RadioMenuItem* item) {
if (item->get_active()) {
// Do some stuff
}
}
That's what I do too, connect to signal_toggled() and check if get_active() is true.
I don't know exactly what you're trying to accomplish (or what MyClass is and what base classes it inherits from), but connecting to signal_toggled() might be more useful than signal_activate()
/Agree with Johannes. Check if the item is activated when receiving the signal.