Showing posts with label Interface Builder. Show all posts
Showing posts with label Interface Builder. Show all posts

Thursday, January 10, 2013

Page Control for Switching Between Views

This is a tutorial request from Ze Kitez.

As much as possible, I tried to do everything in Interface Builder, but sadly, some of the logic could not be done in IB.

1. Create a New Xcode Project, choose Single View Application template.


A ViewController will be created for us.

I'm using the latest Xcode up to date, so you may see a longer UIView in our xib file (for iPhone 5 devices). But if you want the old UIView size, you may change it by choosing Retina 3.5 Full Screen on the Simulated Metrics (right panel of the image above).

2. Search for a ScrollView object from the Objects Library (Lower-Right panel) and drag the ScrollView to the UIView (the gray rectangle above).
Leave a small space below the scrollView so that we can put the PageControl on that area.

3. Search for a PageControl object from the Objects Library (Lower-Right panel) and drag it just below our scrollView.

4. Add a <UIScrollViewDelegate> on your Interface header.
//You may put it in your .h file
@interface ViewController : UIViewController <UIScrollViewDelegate>
//OR in your .m file, directly above the @implementation header
@interface ViewController ( ) <UIScrollViewDelegate>

Read about Interface And Implementation topic to know the difference of the two.

5. Add an IBOutlet property for scrollView and pageControl in your interface.
@property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
@property (nonatomicstrongIBOutlet UIPageControl *pageControl;

And, synthesize these properties in your implementation section.
@synthesize scrollView;
@synthesize pageControl;


6. Connect your IBOutlet properties to the objects in your .xib file.

7. Right-click on your scrollView object in your .xib file. Set the delegate to the File's Owner.

8. Click the scrollView object in your .xib file and only check the Scrolling Enabled and Paging Enabled.

9. Click the pageControl object in your .xib file.
  • Set the number of Pages you want. Number of Pages == number of PageControl dots
  • Change TintColor according to your preference. 
    • Tint Color is for the normal color of the pageControl dots
    • Current Page is for the currently selected page


The rest of the tutorial will be done programmatically.

//In this tutorial, I added three images to my project, namely, image1, image2, image3.



10. Add an NSArray property to your interface (.h) and synthesize your array to your implementation (.m) file.
@property (nonatomicstrong) NSArray *imageArray; //.h
@synthesize imageArray; //.m


11. In your viewDidLoad, add these codes.
- (void)viewDidLoad
{
    [super viewDidLoad];
//Put the names of our image files in our array.
    imageArray = [[NSArray alloc] initWithObjects:@"image1.jpg", @"image2.jpg", @"image3.jpg", nil];
    
    for (int i = 0; i < [imageArray count]; i++) {
//We'll create an imageView object in every 'page' of our scrollView.
        CGRect frame;
        frame.origin.x = self.scrollView.frame.size.width * i;
        frame.origin.y = 0;
        frame.sizeself.scrollView.frame.size;
        
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
        imageView.image = [UIImage imageNamed:[imageArray objectAtIndex:i]];
        [self.scrollView addSubview:imageView];
    }
//Set the content size of our scrollview according to the total width of our imageView objects.
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [imageArray count], scrollView.frame.size.height);
}

11. Implement the scrollViewDidScroll method of ScrollViewDelegate.

#pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
    // Update the page when more than 50% of the previous/next page is visible
    CGFloat pageWidth = self.scrollView.frame.size.width;
    int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    self.pageControl.currentPage = page;
}

12. Hit Run and you're done!








Monday, December 17, 2012

Table Search Display Tutorial

This is what we want to achieve in this tutorial:

A table list with a search bar on top, and when we type on the search bar, the table updates its list.

Prerequisite in learning this tutorial is a knowledge in creating table views. If you still don't know how to make table views, refer to the old tutorials.  (http://iosmadesimple.blogspot.com/2012/10/adding-uitableview-tutorial.html)

1. Create a New Xcode project, choose a Single View Application template.

I'm using the latest Xcode up to date, so you may see a longer UIView in our xib file (for iPhone 5 devices). But if you want the old UIView size, you may change it by choosing Retina 3.5 Full Screen on the Simulated Metrics (right panel of the image above).

2. Look for "Search Bar and Search Display Controller" in Objects Library and drag it to our UIView.


3. Set up the table, the list of items, implementation of the delegate and datasource methods of tableview and everything else. If you have no idea how, follow this tutorial about adding UITableView. (http://iosmadesimple.blogspot.com/2012/10/adding-uitableview-tutorial.html)

4. Add this to your interface header, together with your UITableViewDataSourceUITableViewDelegate:

UISearchDisplayDelegate, UISearchBarDelegate

5. We need to add two more variables:
A boolean variable that will tell us if the user is currently searching;
and a mutable array where we can put the filtered list when the user is searching.

BOOL isSearching;

NSMutableArray *filteredList;

6. Set the boolean variable to NO, and allocate and initialize the filteredList in our viewDidLoad function:
isSearching = NO;
filteredList = [[NSMutableArray alloc] init];

7. Create a method that will add an object to our filteredList according to the string typed by the user.

- (void)filterListForSearchText:(NSString *)searchText
{
    [filteredList removeAllObjects]; //clears the array from all the string objects it might contain from the previous searches
    
    for (NSString *title in list) {
        NSRange nameRange = [title rangeOfString:searchText options:NSCaseInsensitiveSearch];
        if (nameRange.location != NSNotFound) {
            [filteredList addObject:title];
        }
    }
}


8. Implement the search display delegate methods.
#pragma mark - UISearchDisplayControllerDelegate

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
//When the user taps the search bar, this means that the controller will begin searching.
    isSearching = YES;
}

- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
//When the user taps the Cancel Button, or anywhere aside from the view.
    isSearching = NO;
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterListForSearchText:searchString]; // The method we made in step 7
    
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
    [self filterListForSearchText:[self.searchDisplayController.searchBar text]]; // The method we made in step 7
    
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

9. Update our tableview method numOfRows: and cellForRow:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    if (isSearching) { 
        //If the user is searching, use the list in our filteredList array.
        return [filteredList count];
    } else {
        return [list count];
    }

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    
    // Configure the cell...
    NSString *title;
    if (isSearching && [filteredList count]) {
        //If the user is searching, use the list in our filteredList array.
        title = [filteredList objectAtIndex:indexPath.row];
    } else {
        title = [list objectAtIndex:indexPath.row];
    }
    
    cell.textLabel.text = title;
    
    return cell;
}

10. Hit Run and your search display controller is done!

Saturday, September 22, 2012

Tabbed Application, Using Interface Builder


If you want to create a Tabbed Application programmatically, refer to this tutorial:
http://iosmadesimple.blogspot.com/2012/09/tabbed-application-doing-it.html

Let's create a Tabbed application using Interface Builder! :D

1. Create a new empty application. Make your own MainWindow.xib file, you already know how to do this. (If not, refer to this tutorial: http://iosmadesimple.blogspot.com/2012/08/creating-our-own-mainwindowxib-for.html)

2. Go to AppDelegate.h, add a UITabBarControllerDelegate
@interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>

3. add a UITabBarController property.
@property (strong, nonatomic) UITabBarController *tabBarController;

4. Synthesize your tabBarController variable in AppDelegate.m.

5. Create at least 2 View Controllers, name it First and Second ViewController. Add UILabels and other stuff, to indicate that such UI belongs to either of the two ViewControllers.

6. Add "IBOutlet" to UIWindow and UITabBarController properties in AppDelegate.h
@property (strongnonatomicIBOutlet UIWindow *window;
@property (strongnonatomic IBOutlet UITabBarController *tabController;

7. Go to your MainWindow.xib, Search for Tab Bar Controller from Objects Library and drag it to Placeholder/Objects Panel. Make the necessary connections from your AppDelegate Object outlets to your objects UIWindow and UITabBarController.

8. Right-click Window object in your Interface Builder, connect the "rootViewController" outlet to UITabBarController object.



9. Go to AppDelegate.m, under application:didFinishLaunchingWithOptions function, comment out all the codes inside that function, but leave these codes behind:
[self.window makeKeyAndVisible];
return YES;

10. Hit Run!

Let's set our two view controllers that we created a while a go, the First and Second View Controller.

11. Import the First and Second VC to your AppDelegate class.

12. Expand the Placeholders/Objects Panel, and the  TabController.

13. Select one of the two view controllers inside the Tab Controller, and change its class to "FirstViewController."

Do the same thing with the other view controller, set its class to "SecondViewController."

Hit Run and you're done! 




Note

You may add an image or a tabTitle for every ViewController by following these steps:

Expand the Placeholder/Objects Panel, the TabBarController object, and the ViewControllers under it. Click the "Tab Bar Item." Go to Attributes Inspector, the fourth button, next to "Identity Inspector." Change the Title or the Image under the "Bar Item" Category.

For the images, you have to import those images to your project first. Right-click the folders on the Project Navigator, choose "Add Files to project_name," choose the images you want to import.




Monday, September 17, 2012

UIPickerView Tutorial


1. Add a New File, subclass of ViewController, to your project. In my example, the name of my class is ViewController.

2. Open ViewController.xib and drag a pickerview to your xib file.



 3. Add a UIPickerView IBOutlet to your ViewController.h file, and synthesize it to your ViewController.m.
@property (nonatomic, strong) IBOutlet UIPickerView *myPickerView; //.h
@synthesize myPickerView; //.m

4. Connect your IBOutlet property to the object in your .xib file.


5. Go back to your ViewController.h, and make your interface header look like this:
@interface ViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate

6. On your viewDidLoad, set the delegate and datasource of your pickerview to self;
- (void)viewDidLoad
{
    [super viewDidLoad];
    myPickerView.delegate = self;
    myPickerView.dataSource = self;
}

7. Add an array that will hold your items for you.
If your items are constant, use NSArray, else, use NSMutableArray.
@property (nonatomicstrong) NSArray *itemsArray; //.h
@ synthesize itemsArray; //.m

8. Initialize your array.
itemsArray = [[NSArray alloc] initWithObjects:@"Item 1", @"Item 2", @"Item 3", @"Item 4", @"Item 6", nil];

9. Add these delegate and datasource methods of pickerview in your ViewController.m class:
#pragma mark - UIPickerView DataSource
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return [itemsArray count];
}

#pragma mark - UIPickerView Delegate
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
    return 30.0;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return [itemsArray objectAtIndex:row];
}

//If the user chooses from the pickerview, it calls this function;
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    //Let's print in the console what the user had chosen;
    NSLog(@"Chosen item: %@", [itemsArray objectAtIndex:row]);
}

10. Done! Hit Run!





Monday, September 3, 2012

Navigation-Based Project, Using Interface Builder

If you have decided to make Navigation-Based Projects through coding, refer to this tutorial: http://iosmadesimple.blogspot.com/2012/08/navigation-based-project-doing-it.html

Create an Empty Application Project.


1. Make MainWindow.xib file, make all the necessary steps and connections --> you already know how to do that! 
If not, refer to this tutorial: http://iosmadesimple.blogspot.com/2012/08/creating-our-own-mainwindowxib-for.html

2. In our AppDelegate.h, add "IBOutlet" to our UIWindow property.
@property (strong, nonatomic)IBOutlet UIWindow *window;

3. Comment out the codes in AppDelegate.m, application:didFinishLaunchingWithOptions: function
    //self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    //self.window.backgroundColor = [UIColor whiteColor];


4. Go to MainWindow.xib, check the connections between your File's Owner, Object and Window.
 

5. Drag Navigation Controller from Objects Library, put it in the Placeholder/Object Panel with the File's Owner, Object, and UIWindow. 
6. Add a UINavigationController object in AppDelegate.h and connect navController variable to our NavigationController object in .xib


7. Right-click Window object in .xib, you'll see a "rootViewController" outlet. Connect it to the navigationController object. //this action corresponds to this line of code self.window.rootViewController = navController_; 


8. Expand the "Placeholder/Objects Panel" in Interface Builder.
9. Click the Navigation Controller Button on the left side. You should see objects like Navigation Bar, UIViewController, and under UIViewController, Navigation Item.



Let's create our first view!


Make a new file, subclass of UIViewController, let's name it FirstViewController. Play around with its xib file, add some labels and buttons. I added a label and a button to FirstVC's xib file.

10. Select UIViewController, change its class to "FirstViewController." You know where the Identity Inspector is! //Don't forget to import FirstViewController Class!




11. Hit Run!

Let's create a new ViewController Class, name it SecondViewController. Put some labels and buttons for its UI.

1. In FirstViewController.m, let's add an IBAction function. We can show the SecondViewController by:
-(IBAction)goToSecondVC:(id)sender {
    SecondViewController *secondVC = [[SecondViewController alloc] init];
    [self.navigationController pushViewController:secondVC animated:YES];
}
Make sure you imported the SecondViewController class in FirstViewController.
2. Connect the IBAction to your UIButton in InterfaceBuilder. TouchUpInside.
3. Done! Hit run!

When you click the button in the SampleViewController, you should be navigated to the SecondViewController.
/*Optional*/
If you want to add a Navigation Title to your SecondView, put this in SecondVC's viewDidLoad function. 
self.title = @"Second VC";

4. Without adding a code for a back button, UINavigationController automatically makes it for you. As you can see in your SecondViewController, there's a backbutton titled "Root View Controller"  <-- the Navigation Title of the previously showed ViewController.


UINavigationController keeps track of the ViewControllers opened by the user. It's a STACK of ViewControllers. The very firstVC or the rootVC is the first one in the stack, when you click the button to go to the next VC, it will push the second VC to the stack. And when you tap the "back button," it pops the second VC, thus, showing the previous VC.


Tuesday, August 28, 2012

Switching to Different Views with UIViewController

Now that we know how to make our own MainWindow.xib, it's about time to know how to switch from different views (with UIViewController).
If you have not read the tutorial on how to make our own MainWindow.xib, please read this first:
http://iosmadesimple.blogspot.com/2012/08/creating-our-own-mainwindowxib-for.html

1. If you still have your xcodeproj when we created MainWindow.xib, please use it before we proceed. Else, do follow the steps from the given link above before you proceed.

2. Let's add a new file, UIViewController subclass, name it FirstViewController.

3. In FirstViewController.h, I "prepared" these lines of code.  Create a UIButton outlet, and an IBAction method for that button.

4. In FirstViewController.m, synthesize your button, and implement the IBAction method we declared in .h file, but let us leave it blank first.

5. In FirstViewController.xib, I dragged a label and button object to the view (white rectangle). Since we created an IBOutlet button property in our .h file, it is expected that we can see our button variable when we 'right-click' the File's Owner (yellowish box).


6. Did you see that circle at the right side of secondViewButton (our button variable name)? We have to drag that to the UIButton object found in our View. Same goes with our IBAction method, we named that function goToSecondView, drag that circle to the button in our View. That means that if the user taps that button in our View, it will trigger an event, whatever happens after tapping that button depends on our code for goToSecondView function.

7. Open AppDelegate.h, import FirstViewController file, and create an outlet variable of FirstViewController.

8. Synthesize your FirstViewController variable, and add the line self.window.rootViewController = firstVC; 
This line means that the very first view that will be shown to the user is the view we created in our FirstViewController class.

9. Go to MainWindow.xib, drag a ViewController object to the Placeholder/Objects Panel. Go to the Identity Inspector of that ViewController object and change its class to FirstViewController.

10. Right-click AppDelegate object (yellow box), look for the variable we created in our .h file, in this case, its named firstVC, and connect it to the ViewController object we dragged awhile ago.

11. Hit "Run" and you should see this in your simulator. This view is from our FirstViewController class, right? If you click that button, nothing happens yet because we left the method (goToSecondView) blank.
If you see this, it means you have successfully linked the FirstViewController to your AppDelegate Class.

12. Create another ViewController subclass, name it SecondViewController. Add two buttons, "back" and "goToThirdViewButton." Prepare the IBAction methods of the two buttons (IBAction)goBack and (IBAction)goToThirdView.

13. Synthesize and implement the functions in SecondViewController.m, but let's leave it blank first.

14. Drag a Label and two Round Rect Button objects to the View. Make the necessary connections needed.

15. Open FirstViewController.m, import SecondViewController and add these lines of code to our (IBAction)goToSecondView method.
SecondViewController *secondVC = [[SecondViewController alloc] init];
[self presentModalViewController:secondVC animated:YES];

16. Open SecondViewController.m, add this line of code for the "back" button method. This code dismisses the secondViewController and shows the FirstViewController.

If you want to go to another view, let's say thirdView, do the same thing for the SecondViewController, create a new class, add a button "back" and implement it. Add the same lines of code from Step 15 to your (IBAction)goToThirdView method.

Run and you should be able to go to different views. :D






Blocks From one Class to Another

One popular scenario in using blocks is when you need to update your view after a web service call is finished.