Showing posts with label IB. Show all posts
Showing posts with label IB. 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.




Sunday, September 9, 2012

Navigation Controller FROM Another View Controller

Or you may say "Navigation Controller as the second View," or "Navigation Controller's previous view is a ViewController." The purpose of this post is that the NavController is shown after a normal VC or any other views.

Our previous posts about Navigation Controllers only tackle about making it as our very first view. Now, what if you don't want your Navigation Controller as your first view? What if you want your first view to be a View Controller?

1. Create a New Project.

  • If you choose an Empty Application, create a New File, View Controller subclass, connect it to your AppDelegate using xib (MainWindow) or code it in application:didFinishLaunching method in AppDelegate.m
  • Or, you may choose Single View Application, a View Controller class is provided for you, and the View Controller Class is already connected to your AppDelegate Class (this is hasle free).

2. Add a label to your first ViewController (VC), and a button.
When we click the button, it must show a new view with navigation bar.

3. Create another ViewController subclass, name it "SecondViewController," add a label to your second VC just to indicate that the view belongs to the secondVC.

4. Go back to your first VC interface file, import your SecondVC. Add a UINavigationController property and synthesize it in your implementation file.

//.h file
@property (nonatomic, retain) IBOutlet UINavigationController *navController;

//.m file
@synthesize navController;



5. Go to your firstVC's .xib file, drag a Navigation Controller object from the Object's Library to your Placeholder/Object's panel (or you may simply double-click the Navigation Controller object from the Object's Library).

6. Connect your outlet to your NavigationController object.

7. Expand the Placeholders/Objects Panel by clicking the button inside the orange circle, expand the ViewController inside the Navigation Controller object. Change the class of that ViewController with the name of the class we create a while ago. In our case, it was the SecondViewController.

8. After changing the class, you must see that the ViewController is changed to "Second View Controller." This tells us that the SecondVC is the rootViewController of our NavigationController. When the NavigationController is shown, the UI of the SecondVC must be the view inside the NavigationController.

9. Go to your first VC's implementation file. Add an IBAction method to your button and let's add a code that will show the NavigationController with the SecondVC's view in it.

- (IBAction)goToNavigationController:(id)sender {
    [self presentModalViewController:self.navController animated:YES];
}
//Remember to connect your IBAction to your button in your .xib file.

10. And you're 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.


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.