IOS 6 application development: No. 3: custom selector-Alibaba Cloud Developer Community

Let's take a look at how the program runs. There is no optimization on any interface, so please ignore the ugly page.

There are only two in total. The first page is the inital page, and a label in the middle is used to show the different choices made by the user. Below is a button in the tool bar, you can switch between two pages after clicking. The second page has a total of 3 spaces, and the top is a custom pick view. There are two columns, the first column shows pictures of animals, and the second column shows the cries of animals. There is a label in the middle and a button at the bottom. You can click the button to return to the previous page.

Because the teaching materials are divided and explained one by one according to the functions, this time the final interfaces and implementation documents of the two pages are taken as a whole, which can be regarded as a review and summary for myself.

Prerequisites:

you need to add a new class named AnimalChooserViewController to the Xcode project navigator. Then, associate this class with the newly added page. It can be seen from the class name that it is the second page. Remember to change the names of the two pages in IB to initial and Anima Chooser respectively. The benefits of this will not be mentioned.

We also need to drag in some resource files, mainly pictures of 7 animals, which can be downloaded from the website of this book. OK, here are four highlights.

First, the interface file of the initial page is ViewControll.h.

#import <UIKit/UIKit.h>
#import "AnimalChooserViewController.h"

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *outputLabel;

- (IBAction)showAnimalChosser:(id)sender;

- (void) displayAnimal:(NSString* )chosenAnimal
             withSound:(NSString* )chosenSound
         fromComponent:(NSString* )chosenComponent;

@property (nonatomic) Boolean animalChooserVivible;

@end
Is it simple,

we need to import the newly created class, because we need to do interaction. A control outputLabel and function showAnimalChosser are very simple. You can drag the mouse in IB to add them. We need a new property: animalChooserVisibile to store the current visibility of the second scenario. There is also a custom function, displayAnimal, which has three parameters: chosenAnima, chosenSound, and chosenComponent. This function is used to receive the information passed from the second scenario and display it on the label.

The following ViewControll.m File:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)showAnimalChosser:(id)sender {
    if(self.animalChooserVivible !=YES){
        [self performSegueWithIdentifier:@"toAnimalChooser" sender:sender]; //preform the animal chooser sence
        self.animalChooserVivible = YES;
    }
}

- (void) displayAnimal:(NSString *)chosenAnimal withSound:(NSString *)chosenSound fromComponent:(NSString *)chosenComponent{
    NSString* animalSoundString;
    animalSoundString = [[NSString alloc]
                         initWithFormat:@"You changed %@ (%@ and the sound %@)",
                         chosenComponent,chosenAnimal,chosenSound];
    self.outputLabel.text = animalSoundString;
}


- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    ((AnimalChooserViewController *) segue.destinationViewController).delegate = self;
}

@end
the implementation file mainly completes three functions: showAnimalChooser is the function performed when the user clicks the button on the toolbar: determine when the second scene is displayed, switch. Note that you must name the scene switching in IB as toAnimaChooser. Otherwise, manual switching cannot be completed.

displayAnimal the three parameters that the function receives and modify the text content of the label. The function is called after you click Done on the second page.

prepareForSeque function: to use the property delegate to access the initial scenario, we will immediately see that the property is added to the AnimalChooserViewController interface file, so call this function here to set the properties of the initial scenario.

AnimalChooserViewController.h:

#import 
   
    
            
             
     
     #import "ViewController.h" @class ViewController; @
    
     
             interface AnimalChooserViewController : UIViewController 
    
     
             
              
      
      @property (weak, nonatomic) id delegate; - (IBAction)dismissAnimalChosser:(id)sender; - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender; @end @interface AnimalChooserViewController(){ NSArray* _animalNames; NSArray* _animalSounds; NSArray* _animalImages; } @end
    
     
             
   
    
            
the newly added property id delegate is used to access the initial scenario.

A function: dismissAnimalChooser. When the user clicks the DONE button, it returns to the initial interface.

Here, we need to name the three arrays as private variables. The private variables of OC are named like this. Please remember.

Why do we need to call 3 arrays for better real animal names, because the original picture is. png, of course we don't want to realize this, so we need to remap the name, sound and picture.

Note that it is added after interface AnimalChooserViewController: UIViewController , is used to call several functions of the custom selector. Used in the implementation file.

AnimalChooserViewController.m:

#import "AnimalChooserViewController.h"
#define kComponentCount 2           //define how many columns will be performed in the pick view
#define kAnimalComponent 0          //the index for the first column
#define kSoundComponent 1           //index for the second column

@interface AnimalChooserViewController ()

@end

@implementation AnimalChooserViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _animalNames = @[@"Mouse", @"Goose", @"Cat",@"Dog",@"Snake",@"Bear",@"Pig"];
    _animalSounds = @[@"Oink",@"Rawr",@"Ssss",@"Roof",@"Meow",@"Honk",@"Squeak"];
    _animalImages = @[
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mouse.png"]],
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"goose.png"]],
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cat.png"]],
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"dog.png"]],
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snake.png"]],
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bear.png"]],
                      [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pig.png"]],
                      ];
}

- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    //Do any additional after view has been displayed
    
    ViewController* initialView;
    initialView = (ViewController*)self.delegate;
    [initialView displayAnimal:_animalNames[0] withSound:_animalSounds[0] fromComponent:@"nothing yet be chooosen"];
}


- (void)viewWillDisappear:(BOOL)animated{
    ((ViewController *)self.delegate).animalChooserVivible = NO;
}



- (NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return kComponentCount;
}

//founctions in the protocol "UIPickerViewDataSource"
- (NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    if(component == kAnimalComponent){
        return [_animalNames count];
    }else {
        return [_animalSounds count];
    }
}

//-----------------------------------------------------------------------//
// founctions in the protocol "UIPickerViewDelegate"
- (UIView* ) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
    if (component == kAnimalComponent){
        return _animalImages[row];
    } else {
        UILabel* soundLabel;
        soundLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 32)];
        soundLabel.backgroundColor = [UIColor clearColor];// make the Rect into the background, because the color is transparent
        soundLabel.text = _animalSounds[row];
        return soundLabel;
    }
}

//set the height of one single row
- (CGFloat) pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
    return 55.0;
}

//set the width of the diffenret column
- (CGFloat) pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
    if(component == kAnimalComponent){
        return 75.0;
    }else {
        return 150.0;
    }
}

//after user selected one row
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    ViewController* initialView;
    initialView = (ViewController* )self.delegate;
    
    if(component == kAnimalComponent){
        int chosenSound = [pickerView selectedRowInComponent:kSoundComponent];
        [initialView displayAnimal:_animalNames[row] withSound:_animalSounds[chosenSound] fromComponent:@"the Animal"];
    }
    else{
        int chosenAnimal = [pickerView selectedRowInComponent:kAnimalComponent];
        [initialView displayAnimal:_animalNames[chosenAnimal] withSound:_animalSounds[row] fromComponent:@"the Sound"];
    }
}

//-----------------------------------------------------------------------//




- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (IBAction)dismissAnimalChosser:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil]; // manual close this sence.
}
@end
the implementation file is a bit long, don't worry, just look at it separately.

First# define several names, and I mark them with comments.

In the ViewDidLoad function, three private arrays are initialized,

viewDidAppear function, initialize the interface, set the selector to the 0th image and the 0th sound, and then set the text to nothing yet been chosen. The default selector status. Note that the function of the initial interface has been called here. If the user returns to the first interface without making any changes, the user can be prompted correctly.

viewWillDisappear

set the initial attribute to NO,

numberOfComponentsInPickerView

we see the functions in the protocol contained in <> in the header file. This method returns several components in the selector. Here we have two columns, and the number has been# define.

//founctions in the protocol "UIPickerViewDataSource"

-( NSInteger ) pickerView :( UIPickerView *)pickerView numberOfRowsInComponent :( NSInteger )component {

    If (component == kAnimalComponent ) {

        return [ _animalnames count ];

} else {

        return [ _animalsounds count ];

}

}

I marked the method in the protocol datasource, numberOfRowsInComponent, to return the number of elements contained in each component. The number of arrays can be obtained by using the count function.
// founctions in the protocol "UIPickerViewDelegate"
- (UIView* ) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
    if (component == kAnimalComponent){
        return _animalImages[row];
    } else {
        UILabel* soundLabel;
        soundLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 32)];
        soundLabel.backgroundColor = [UIColor clearColor];// make the Rect into the background, because the color is transparent
        soundLabel.text = _animalSounds[row];
        return soundLabel;
    }
}

//set the height of one single row
- (CGFloat) pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
    return 55.0;
}

//set the width of the diffenret column
- (CGFloat) pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{
    if(component == kAnimalComponent){
        return 75.0;
    }else {
        return 150.0;
    }
}

//after user selected one row
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    ViewController* initialView;
    initialView = (ViewController* )self.delegate;
    
    if(component == kAnimalComponent){
        int chosenSound = [pickerView selectedRowInComponent:kSoundComponent];
        [initialView displayAnimal:_animalNames[row] withSound:_animalSounds[chosenSound] fromComponent:@"the Animal"];
    }
    else{
        int chosenAnimal = [pickerView selectedRowInComponent:kAnimalComponent];
        [initialView displayAnimal:_animalNames[chosenAnimal] withSound:_animalSounds[row] fromComponent:@"the Sound"];
    }
}

//-----------------------------------------------------------------------//
These functions are all methods in the DateViewDelegate protocol. When you include this protocol in the header file, the compiler will automatically complete the function you want to write in the interface file, good UE!

The first function provides a custom view for each selector element. Here, a label is manually added and two return values are required. Otherwise, XCode will prompt you for an error. Note that the background of the label is clearColor. A transparent color object is returned. Otherwise, the rectangle will not be merged into the background of the selector view.

The second function sets the height of each row.

The third function sets the width of different columns. These numbers can be corrected continuously to achieve the most satisfactory effect. In other words, the program may be relatively small, I always feel that iOS is deployed very fast, much faster than android....

The last function is the response when the user makes a choice. In fact, it attaches the correct values to the three parameters to be passed to the initial page.

Implement the last function of the file

-( IBAction )dismissAnimalChosser :( ID )sender {

[ self dismissViewControllerAnimated : YES completion : nil ]; // manual close this sence.

}

because it is an iPhone version, you need to manually close the scene. If it is an iPad, because a dialog box pops up, you can click somewhere else to close it, therefore, this function can only be used on iPhone.
Selected, One-Stop Store for Enterprise Applications
Support various scenarios to meet companies' needs at different stages of development

Start Building Today with a Free Trial to 50+ Products

Learn and experience the power of Alibaba Cloud.

Sign Up Now