UIAlertView events - ios

I'm trying to write a simple message alert system, with a UIAlertView displaying when priority messages are collected from a server. The messages are sent as a Tab separated string in the following format:
Priority:TRUE\tTrackingID:MESSAGEID\tFrom:FROMUSERNAME\tFromID:FROMID\tSentTime:SENTTIME\tMessage:text
Messages are displayed as a list in a table view. Clicking on a cell segues to a detail view with the message content. If a message is marked as priority an alert should appear which, on dismissal, directs the user straight to the detail view for that message.
The code I have for dealing with each string is:
NSArray *msgArray = [messageString componentsSeparatedByString:#"\t"];
[self storeMessageData:msgArray];
Then:
- (void) storeMessageData: (NSArray *)messagesArray
{
if ([messagesArray[0] isEqualToString:#"Priority:True"])
{
[self alertWithMessage:#"priority"];
}
}
And:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
[self performSegueWithIdentifier:#"showPriority" sender:self];
}
}
This works OK if only one message is retrieved but if there are two or more, dismissing the alert still performs the segue but then the alert immediately pops up again, followed by another segue, for as many times as there are messages.
What I'd like to know is how I'd go about interrupting this process, so that the user is able to deal with the first message then, if there is more than one, another alert is shown on returning to previous view. Any ideas appreciated.

Instead of looping through all your messages and calling the method that displays an alert for each of them, which results in the multiple alerts being displayed to the user, while looping, add all the 'priority' messages in an array. Then, check the number of alerts in your array and you can show one alert that reflects this information: e.g. for one message you could display the title of the message and some other information as title and message of the alertView, while, when you have multiple messages, you could have a title stating something like "You have x new messages with high priority" where x is the number of messages and some other description.

Related

iOS how to present a view, then rerun calling method with input from the view

I'm working on an iOS app that uses a tab bar. An item is scanned using a barcode reader, and a callback method sets the tab bar item to the result view, then sends the request to the server. The callback from the server populates the display and the result view is shown.
However, under certain conditions which depend on the response from the server, I'd like show an alternate view which allows the user to manually enter the data, and then process the data in the same way as the callback. The manual entry display can't be shown on the tab bar.
So I create a modal view and exit the callback:
EnterTextController* enterTextController = [[EnterTextController alloc]init];
presentModalViewController:enterTextController animated:YES];
return;
In the view, I take the input and call the same process called by the callback:
NSLog(#"Button Clicked!");
NSString *myText = myInput.text;
[self dismissViewControllerAnimated:NO completion:nil];
[self.mainViewController processMyText: myText];
The problem is the processMyText doesn't get executed. I have a breakpoint set and it never hits it.
I'm sure I'm not going about this correctly. Any suggestions would be welcome.
Make sure the receiver isn't nil.

How to return to a loop after button press

I am taking an online course and one of the problems has you build a simple number guessing game. That was easy enough. However, I want to modify it to limit the number of guesses. That would entail a loop for the number of guesses allowed.
When I try this, the code goes to the button press action and never returns to the loop. I have tried everything I know to get it to work, google searches have not helped, and the instructor has not answered my question posted 4 days ago!
So in short how does one get code to return to a loop after finishing the code for the button press?
In words here is what I want to do:
generate random number
for x = 1 to 6
get user guess in text field
press button to check if correct
if correct
do something
else
continue loop for another guess
x = x+1
You can't do what you want.
The user interface is an event-driven activity -- things happen as a result of the user typing in a textField or tapping a button. The code to handle the UI is distributed among the response routines that handle the events and you have to figure out where you can do each part of what you want to do. It can be maddening!
A general answer is that the code to handle events is distributed among multiple methods and you have to have some sort of shared state so that each event response can know what to do. Some code somewhere starts a round of the game and initialize the number of guesses. Your textField delegate routines get the user guess and store it in an instance variable or property. When the user taps a button, the button-response code can check the answer in that property and keep track of the number of guesses.
To be specific, here is some pseudocode that does what you proposed in your question:
#property (strong, nonatomic) NSString *currentGuess;
#property (nonatomic) int numberOfGuesses;
- (void) startNewRound {
...
// some code that gets ready for the user to guess
generate random number
// initialize the number of guesses where button code can get at it
self.numberOfGuesses = 0;
...
}
// This method is called when the user finishes typing
// a guess in the text field as a result of the user pressing Return
// (or however you manage the data entry). The parameter is whatever
// the user typed as a guess.
- (void) userEnteredAGuess:(NSString *)guess
// put the guess where the button-event code can get at it
self.currentGuess = guess;
}
// This is the method that gets run when the user taps the
// "Check the Guess" button
- (IBACTION) tapButton:(UIButton *)sender {
if (the guess in self.currentGuess is correct...) {
// Do whatever you do when the guess is correct
} else {
// Do whatever you do when the guess is wrong
}
self.numberOfGuesses += 1;
if (self.numberOfGuesses > guessLimit) {
// Exceeded guess limit
// Do whatever should happen --
// re-initialize the guesses, decrement score, ... whatever
// maybe...
[self startNewRound];
}
}

Calling UIAlertView in block displays view multiple times

I have a block completion being called from within a button press message and, depending on state, optionally a UIAlertView being displayed. However, when invoked the UIAlertView appears three (3) times...
With the full information but it disappears itself and shows
Just the title shows and when I click OK
Appears again with full information (as in #1) for which I have to dismiss again
Following is a snippet of the code:
[credential performDataOperation:[credential commandForCreateOnClass:self.className]
withArguments:edits
completionBlock:^(BOOL succeded, id before, id after, NSDictionary *arguments, NSError *error) {
if (succeded) {
self.object = after;
self.objectWasCreated = YES;
[self prepareEditsDictionary];
self.navigationItem.rightBarButtonItem.enabled=NO;
}
else {
errorRecieved = YES;
[[[UIAlertView alloc] initWithTitle:#"Error" message:#"Error Message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
}];
You are probably seeing just two alerts. The first appears, but you also have code somewhere that summons the second, so it overrides the first. Then you dismiss the second and the first returns. You need to hunt for your code that presents the second alert, the one without the message, and figure out why that code is running. Just do a global search in your project for UIAlertView! It must be in there somewhere, because all alert views are created and presented in code.
You may have accidentally hooked up your button so that it has multiple action handlers. Of course I could be wrong, but this is a mistake I've sometimes made, and then I've been mystified why my method was being called twice or some unwanted extra thing was happening when I tapped the button. Check your nib/storyboard or code to make sure. The fact that a single button can have many actions for a single UIControlEvent is very surprising and is almost never used intentionally.
(If that's not the right answer, then perhaps the solution lies in your performDataOperation method, whose code you do not show. Maybe it calls the simpler UIAlertView, in addition to calling the block.)

UIPageViewController - Verifying Page Turn with alert

I'm using a UIPageViewController to handle data entry where the last page is the active record and the previous pages are old records that can't be edited. So I need a way to verify that the user wants to leave the last page while allowing all of the other pages to navigate as usual.
Ideally I could really use a -(BOOL)pageShouldTurn method but that doesn't exist.
Does anyone know of a way to detect if a page is about to unload then stop the page turn based on some condition? I'm not having any luck with the gesture recognizer methods as they don't seem to be triggered even when the delegate is set.
Thanks to Michael, I've added this to my pageViewController which does exactly what I needed:
-(void)pageViewController:(UIPageViewController *)pvc willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
if ([pvc.viewControllers.lastObject pageIndex] == [self.pageDataSource.allObjects count]) {
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc]
initWithTitle:#"Are You Done?"
message:#"Once you leave this page you can't edit this record again"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertDialog show];
}
}
So the alert box stops the page from turning only once. When it is dismissed, the user can then change the page. My version checks to make sure this only happens on the last page, you could remove the 'if' statement and alert on every page turn, but that would be annoying.
Seems to me there are at least two options.
Number one, you have "- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers". You might be able to catch a transition there and deny / force the old page to be reset.
Or, you can now subclass "UIPageViewController" and in your subclassed controller, you can define a new delegate protocol (incorporating all the original UIPageViewControllerDelegate" methods) and you can add your own "-(BOOL) pageShouldTurn" protocol method.
Both of these possibilities require iOS 6.

How to show the text of an UITextField in an UILabel?

I am building an interface, where I can add events like in a calendar.
In the AddAEventViewController I have Buttons to set the starttime, duration and recurrence.
Every time you press a button a viewcontroller comes up with a UIDatePicker, where you can set your time. The picked component is than displayed in a UITextField. Now when I press the Done-Button, it dismisses the ModalViewController and I am back to my AddAEventViewController. Next to the Durationbutton e.g. is a UILabel, where I want to show now the just picked and in the textfield shown duration.
How do I get access to the AddEventViewController out of an other ViewController? I tried to alloc and init a new one there, but it didnt work!
- (IBAction)pressedDoneButton:(id)sender {
_mainAddWishViewController.labelDuration.text=textFieldDuration.text;
[self dismissModalViewControllerAnimated:YES];
}
Can someone help me please!
Thank you Jules
There are several ways you can do this, all of them documented here. Reading and understanding them will help you a lot in iOS software development.
There are many ways to achieve this. Here is one that is fairly straightforward.
In the "child" viewController, add a delegate property and set it to the parent view controller.
Then in your Done button handler, do something like:
[self.delegate performSelector:#selector(didComplete) withObject:self]
In the parent view controller, define a method as follows:
- (void) didComplete: (YourSubViewControllerClass *) sender
{
self.labelDuration.text = sender.textFieldDuration.text
}
Basically, this implements an informal protocol whereby the subViewController informs the main view controller that it is finished and input values are available.
Note that if you cancel out of the subViewController, don't send the didComplete message.

Resources