Cocoa-Touch: How to Change View After Input Validation? - objective-c

I have a single-view application that takes in a username and a password and validates it with the server. After the credentials are validated, I would like the application to go to a different view, which will show some other data.
I only know how to switch views when I have a button (that is, by dragging it to the secondary view and selecting what kind of segue I want to use). But how do I change the view after the credentials are validated?
To give you a more clear idea, here is how my app currently functions:
Text is entered into two fields. Pressing the "Login" button (or the 'done' button on the keyboard) calls a method that validates the entered credentials. If the credentials are valid, then the add should move on. Otherwise, it will pop up a notification saying that the credentials are invalid.
I have everything completed and working. I just need to know how to change the view in the validation method after the given credentials are validated.

There are a number of ways to achieve this; the technique you choose should depend on if you want the validating view controller to "stay around" after you move on. If you want it to stick around, you can actually do it in much the same manner as your storyboard segues from buttons.
In the storyboard, ctrl-drag from the first (validating) view controller to the second to create the segue. Select the segue and use the inspector panel to give it an identifier. Then in your code in the validating view controller, you can do something like this:
[self performSegueWithIdentifier:#"validCredentialsSegue" sender:self];
If you want the originating view controller to "go away", you must look into the architecture of your application flow. Perhaps you want a master view controller "above" the credential's one that is notified via delegation of the successful login and it decides what to do (maybe it's view is the destination view anyway...). Otherwise, I think in the old days people fussed around with setting the window's rootViewController property. I'm confident there are better techniques, though.

Related

Best way to implement UIPageControl?

In my app I have a registration page for any new users. At the moment Im using UIPageControl on a view controller so that when a user swipes left a new set of textfields are displayed. I have it so that when the user swipes to the left the previous textfields are hidden. I don't think this is the best way of implementing UIPageControl. I would like to implement it in such a way that when the user swipes to the left the new text boxes slide in with the swipe instead of just appearing. Also when the user swipes back i have to make the previous text fields unhidden but then they don't keep the information that the user has already typed into them.
Any ideas of how to best implement UIPageControl or even the best way to implement a registration form like this?
Thanks a million!
If this is a march through a series of forms that the user must fill out in order, you could use instead a UINavigationController (which, indeed, is what is suggested by the Back button already in your interface)...
The real problem, however, seems to be that you are using UIPageViewController incorrectly: if the user is to be able to go back and forth between views and the information previously entered is to be present, it is up to you to use a different view controller for each view and to save the entered information when the user leaves a view controller and to restore it when the user summons that same view controller again.
This is something you would need to do no matter what implementation you choose, because a view controller can always be destroyed when its view is not being seen. Model-view-controller! It is up to you to maintain the model (the data) - do not rely on the mere view to maintain it for you.

Is there a way to disable sounds (such as "beeps") in my mac app?

I know I need to dig the reason why my app is beeping in the code, etc.
But I was wondering, is there a global setting to disable sounds all over my app screens?
this is very little information to go on, but usually your application is beeping when the responder chain comes up with no object that can respond to an event on the screen or keyboard.
For instance, if you type text in an active view and the view doesn't allow for text editing, the view sends the key down event to its super view. For a view this can end by the NSPanel or NSWindow or BSWindow controller. The last responder in the chain invokes the noResponderFor: method, which, when not implemented, will give a beep. If you don't want it to beep, override this method to do something else.
Based on your information I can't give you any other information.

Main Menu in different nibs

I have a Cocoa app with a ManMenu.xib, in which the main menu is stored and different other subviews in several xibs handling different tasks of my app. So how do I make my sub-xibs or rather their NSViewControllerController receive actions from the menu?
i have an idea but I don't know if it's the right way: I subclass NSViewController and add some actions like - (IBAction)undo or - (IBAction)redo use instances of it as the files owner. Further I add a pointer to my app delegate pointing at the actual view or rather its controller and the menu sends the action to that pointer.
Wise solution?
You should hook up your menu items to the First Responder. Their action messages will then travel along the responder chain until they reach something that responds to them.
You'll need to make sure your view controller is in the responder chain by setting it as the next responder of something else in the responder chain. I would suggest the window controller.
Speaking of the window controller, you probably should be handling undo there rather than in a view controller—it would be confusing for different views in the same window to have different undo lists. The only exception I can think of would be if the controlled views correspond to document tabs, like in Photoshop or Xcode.

Delay navigationController to pop detailView of UITableView

Im looking for some help regarding to put a save like confirmation if some changes where made to a UITextField and UISegmentedControl.
Can I prevent the UINavigationController from pop the view? And then pop based on buttons in a AlertView?
I use the UITextField and UISegmented control to POST data to a webservice.
I perhaps need to use a modalView for this? but wanted first to see if someone have another idea, because I would like to keep navigation clicks down if possible.
Any suggestions for this?
Thanks,
Why not just using a UIAlertView?
EDIT: On second thought, and re-reading your question + comment, I would recommend to use a Modal View with classics OK/Cancel buttons + a UIAlertView(s) for confirmation(s). (UIAlertView "poping" on OK/Cancel is easy to do via UIAlertViewDelegate)
That's what Modal views are for, block UI until some user action has been completed. Like a form. This is how I do all my forms, and how Apple does (just look at the create mail screen for an example, or any form of iOS apps)
Adding a "Magical" action requiring user interaction on the back button of a navigation controller is bad in terms of user experience, if you hit back, you expect the view to pop, nothing else. I would then be surprised if Apple SDK even allows to cancel that event...
You can do what you would like without the need of a modal view.
First, you can use your text field's UITextFieldDelegate to set a flag in your controller when the field content is modified. You can reset this flag when the data is sent out.
Then you could override your UIViewContorller's viewWillDisappear to show an alert to the user in case new data have not been posted at the moment the view is going to disappear and give him the possibility of sending it to the server. This method will be called when you move to a different controller in your navigation UI, and you will not have a chance to "reject" the operation.

Problem reading the latest value from UITextField before closing the view

I have a view that I'm displaying modally to get login information from a user. I have the following setup:
The view controller is a UITableViewController
The table has three cells: username and password fields (both of type UITextField within UITableViewCell) and one simple cell as the login button.
Values are read from UITextField in textFieldDidEndEditing:message
The text fields are identified by different tag values.
The problem
My problem is that when the focus is in a UITextField and user touches the login button, the respective UITextField's textFieldDidEndEditing:message is sent after the didSelectRowAtIndexPath:. Now the issue here is that I'm sending a message of new user credentials to my LoginViewControllerDelegate in the didSelectRowAtIndexPath: and at that time the text field's value is not read yet.
Some Ideas
I have some ideas how to fix this, but I have complications with each of them.
First, I could close the login view and the delegate is notified during the closing, but I want to give the delegate (one who owns this login view) full control and I think it should be the delegate's job to close the login view on successful login (the login view only reads the credentials, the delegate validates these).
Second, I could also read the username or password just before calling the delegate but then I'd have to look up the text fields. If the views are not visible, I think it is wrong to assume that the cells do exist. This is just a big if, but I wan't to make it right. Would it be ok to retain the UITextFields? This way, however, I can't use some custom cell that would itself provide the textfield.
Basically I want the following:
Need for (valid) user credentials is detected, login view is popped up
User inputs the username and password and invokes done.
The delegate validates these credentials. If they do not work, a message is shown and try step 2 again.
Credentials are ok, so close the login view and continue.
After all tricks I finally figured that simply resigning the first responder right before invoking the delegate fixed this. In the table view controller I simply had to add a call:
[[self.view findFirstResonder] resignFirstResponder];
The findFirstResonder is from a category and can be found here.
Try this instead of using third cell as login button. Use a simple button on login view. On that button's IBAction you can validate user input.
You can use a simple view with two textfields and one UIButton. After the button is pressed you can just remove the view from superview by [yourView removeFromSuperview] . You can receive the data from the yourTextfield.text.
I guess this must do the trick