Multiple view states in Interface Builder

I work on a screen with three states:

  • Validating
  • Loading
  • Error

The first two are quite simple, since there is only a change in the text of the label. The third one is harder because I need to show the error message and press the redo button on it.

In addition, I would like to have it all under one controller (which, in my opinion, is the easy part).

Question: how do I make several view states in Interface Builder? Has anyone done this before? Or am I going to do it wrong?

+4
source share
4 answers

You can try adding additional views that you add or remove as needed. In the window "File Owner", "First Responder", "View", etc. Add three UIView libraries from the library. You can change their names from “View” to “Verification”, “Download” and “Error”.

Now open each one of them and customize it as you like by adding buttons and tags and other similar things.

Return to Xcode, announce new views:

IBOutlet UIView *validView; IBOutlet UIView *loadView; IBOutlet UIView *errorView; 

and be sure to create the appropriate connections in InterfaceBuilder. Any actions you want to associate with any of these views should work just fine.

Now, to switch, create an action (or three different ones). It can be an IBAction or not, as you like. In the title:

 -(void)showError; 

Now for implementation you may need something like this.

 -(void)showError { // skip this if you always arrive from the validView if ([validView superview]) { [validView removeFromSuperview]; } [self.view addSubview:errorView]; } 

You can get an animation lover if you want:

  -(void)toggleErrorWithFlip { [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.8]; [UIView setAnimationTransition:([errorView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight) forView:[self view] cache:YES]; if ([errorView superview]) { [errorView removeFromSuperview]; } else { [[self view] addSubview:errorView]; } [UIView commitAnimations]; } 

The Repeat button can trigger an action on the lines of the following:

 -(IBAction)retryLoad { [errorView removeFromSuperview]; [self.view addSubview:validView]; // do some stuff that retries whatever was tried and failed } 

Again, this can happen with or without animation.

If there is a default view that you always return (for example, validatingView), then make it the original "View" and just add two other views on top of it (for example, loadView and errorView). This can save a little work depending on how you want everything to go.

+4
source

Your mistake seems to be a great candidate for UIAlertView

 //wherever error is detected UIAlertView *alert = [[UIAlert View alloc] initWithTitle:@"Error" message:@"An error occured" delegate:self cancelButtonTitle:@"Forget It" otherButtonTitles:@"Retry", nil]; [alert show]; [alert release]; //implement the delgate method - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { switch(buttonIndex) { case 0: break; case 1: break; default break; } } 

You will also have to implement UIAlertViewDelegate in your header!

+1
source

Exactly what you do depends on the layout used. The simplest approach that I have used several times is to lay out all the controls and simply mark groups of them as hidden / not hidden in methods such as:

 - (void) showErrorModeControls { self.errorLabel.hidden = NO; self.errorButton.hidden = NO; self.regularLabel.hidden = YES; self.regularButton.hidden = YES; } 

You can also do animations, insert / exit, etc. This is one way.

Another way is to group the controls into sub-items of the main view and show / hide these subtasks as a whole. This only works if you manage to arrange all the views so that when several are visible, you can see the contents of other views. You can use the clearColor background for this. The advantage of this approach is that you can place the controls in separate subprojects separately in the interface builder (you do this with a neat trick: just set the X coordinate of the frames of other views to 320 (or something suitable for your view), to “remove them from the path" of the view you want to edit, then you move them back to the X-coordinate 0 when you are done.

Another approach that I used is to have entire “pages” of views, such as a mini-navigation controller, and insert and view these views themselves, animating their frames “on-screen” and “off-screen”. You can use the same trick in the interface builder above to work on these “pages” one at a time.

+1
source

If you need custom warnings, you can actually use the TSAlertView class. It works pretty nicely and is easy to deploy. This is similar to a UIAlertView, but you can customize it with a UITextView, a few buttons with legends, etc.

0
source

Source: https://habr.com/ru/post/1341295/


All Articles