How do I “connect” a table view to a view controller

北城余情 提交于 2019-12-04 04:24:38
Moshe

If I understand your question correctly, you are asking how to initialize a view controller and pass in some data to alter its behavior. The key concept here to understand is how objects are initialized in Objective-C. One of the most common questions that developers who are new to iOS have is:

How can I pass data between my views?

Yes, eight different links there. (Okay, that eighth link is a little bit off topic, but it's close enough.) There are several ways of doing this and I'll go through them briefly. I'll also describe custom initializers, which are a relevant point as well.

Let's pretend we were building a catalog application which shows a bunch of products in various categories. Imagine that our app opens to a list of products, much like the Apple Store App. Say that when the user taps on a product we want to show a product page.

  1. You can set properties on the "next" view controller. - Simply, we can create a UIViewController subclass and set the productID property (which we made up). Let's call our new UIViewController a ProductPageViewController. Here's how this would look:

    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    
      //Create a ProductPageViewController
      ProductPageViewController *ppvc = [[ProductPageViewController alloc] initWithNibName:@"ProductPageViewController" bundle:nil];
      //set the property on our ProductPageViewController
      [ppvc setProductID:42];
      //We would usually present the PPVC here.
      //After presenting, remember to release the view controller
    }
    

    In the first line, we create the product view controller. We call alloc, then init. (The functions are wrapped - that is, we call init directly on the result of the alloc method.)

    Then, we set a property of our view. The view can now be configured in viewWillAppear and all is well.

  2. You can share the data through a persistent store. - This method works a little differently. The view controllers don't communicate at all, except for the first one presenting a second one. Whenever a value in the first view changes (that you want to persist), you write it to Core Data or NSUserDefaults. Then, the new view reads the value as it needs it.

    In your first view controller:

    //A method to store the data
    - (void)storeData:(id)pageID{
        [[NSUserDefaults setObject:pageID forKey:@"pageID"];
    }
    
    - (void)showNewPPVC{
    
      ProductPageViewController *ppvc = [[ProductPageViewController alloc] initWithNibName:@"ProductPageViewController" bundle:nil];        
      //Show and then release the PPVC
    }
    
  3. You can use custom initializers. - This is probably the most intuitive way to do it, once you understand the concept, because this is the only one where data is actually "passed". (As opposed to method 2 where no data is directly shared and method 1 where data is passed as a property.)

    Notice that in the earlier examples, I used the initWithNibName:Bundle method. You might also notice that UITableViewControllers use a different initializer, initWithStyle:. Those two initializers take in some information for the new object so that it knows how to load. Let's look at the first one first:

    - (id)initWithNibName:(NSString *)nibNameOrNil Bundle:(NSBundle *)bundleNameOrNil;
    

    The first argument tells the view controller which nib file to load up. I'm going to ignore the second argument for now, since I've never seen anything passed in except nil. Moving right along to the second example:

    - (id)initWithStyle:(UITableViewStyle)style;
    

    You can pass in one of two UITableViewStyle values here. This is one way to define the style of a table view (the other way being to modify a nib file directly).

    Let's extend this concept a bit to our example. I'm now going to show you how to make your own custom initializer. Let's initialize our ProductPageViewController instance:

    - (id) initWithProductID:(int)productID;
    

    That's simple enough. Now, we need to implement the method and actually do something with the product ID. We'll start with the barebones code here, required to "mimic" the functionality of the default initializer.

    - (id) initWithProductID:(int)productID{
     self = [super init];
    
     return self;
    }
    

    This method will return an initialized copy of our ProductPageViewController, however, it won't load up our UI from a NIB yet, or if this were a UITableViewController, it wouldn't set the UITableViewStyle. Let's work with a NIB first and then I'll show how to work a UITableViewController. So...

    - (id) initWithProductID:(int)productID{
     self = [super initWithNibName:@"ProductPageViewController" Bundle:nil];
    
     return self;
    }
    

    Now. we have an initialized ProductPageViewController, loaded from a NIB, but it doesn't do anything yet. Notice how we don't expose the NibName and Bundle arguments, but we just pass them in ourselves. If you want, you could theoretically expose those too. Now, let's take that productID and do something with it.

    - (id) initWithProductID:(int)productID{
     self = [super initWithNibName:@"ProductPageViewController" Bundle:nil];
    
       if(self){
         self.prodID = productID;
       }
    
     return self;
    }
    

    With our latest changes, our "PPVC" now knows about the productID. It can query the database as you want and do things with the results. You can then run different queries based on this productID.

Two More Quick Tips:

  1. Perhaps you want to pass in several arguments. Of course you can simply add them to them method signature - (id) initWithProductID:(int)productID andCategoryID(int)categoryID, but what happens if you have five, six, or fifty six (yea, that's a lot) arguments? I'd advise passing in a collection or array of arguments.

  2. To use custom initializers with UITableView, you pass in a UITableViewStyle instead of a NIB name. Here's what it might look like:

          - (id) initWithProductID:(int)productID{
            self = [super initWithStyle:UITableViewStyleGrouped];
    
            if(self){
              self.prodID = productID;
            }
    
            return self;
          }
    

When making your subsections, I'd suggest a combination of persistent data and custom initializers. I also advise taking a peek at the viewDidLoad and viewWillAppear methods.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!