How to "connect" a table view to a view controller

Well, I know this is a vague conceptual question, but I really need help here. Thanks in advance if you decide to take the time to read this. I would never have thought of this, but it is a great forum with so many helpful people that I thought this would be the best place to ask.

All this is connected with the question here (you do not have to look at it - I explain everything below): Skip the parameter when initializing the table

I have been working for several days on the same problem, but I understand that there must be something big that I am missing. I googled and googled, and I even bought (and read about 50%) two Obj-C books a few days ago, but I'm still clutching at what seems to be incredibly easy. I am obviously pretty new to OOP, but I have average skills in HTML, perl, sql, python, as well as some ancient things like pascal and basic. I'm n00b, but not an idiot (well, actually this experience changes my mind a bit).

In any case, my ultimate goal is to simply create an application with 8 "normal" buttons on the first view (level 1), each of which does basically the same thing - to show a simple tabular view (level 2) with data in cells that can be clicked to continue drillthrough (level 3). Very simple and clear concept. The only difference between the 8 possible level 2 is the data that will be displayed. I have already created sql queries that work the way I want for each button.

So, here where I stand: I have a perfectly working application that does everything from level 2, just as I expect - queries work, tables are beautiful - so great.

In addition, I have another navigation application that launches at “level 1” and shows me 8 buttons (I hide the navigation bar at level 1). If I press any of the buttons at level 1, the level 2 view (which is the navigation bar + table) slides into the field of view exactly the way I want. The problem is that the table is just empty. No matter what I do, I cannot get the second level in the second application to show me the data, although I can completely show all this data in the first application. For my life, I can’t understand how to “link” level 1 to level 2.

I hope you understand this gap that I am trying to bridge. Since there are 8 possibilities for level 2 (with very slight differences in sql queries in the same sql table), I first tried to come up with a way to “pass” an integer to a level 2 view (in the first application) and then select the sql query to based on what was transmitted (see link above for this fiasco). Once I got this working, I planned to figure out how to make the buttons later. However, after about 16 hours, I just gave up and decided to make 8 different table view controllers, all with almost identical code, except for the request. Thus, if I could just press the SINGLE button at level 1 to just press only one level 2 with NO parameters, I would be a terrible but successful programmer.

Unfortunately, even this did not work for me. I tried all possible combinations of drag-and-drag-and-window / view / table that I can think of in Interface Builder, but no matter what I try to do, the data is never loaded into the table view, even though that this works great in my first application. I went through each line of code - they are the same, except that something should “trigger” or “start” the level 2 part, and I just don't get it.

So, I'm going to break with the agreement / expectations here, and not post any code in my question. I just want to know how it can be so complicated? I am very analytically inclined and will quickly catch, but I must say that I have never been so confused with the technical difficulties in my life.

Can someone explain to me, conceptually, what I need to do here or what I am missing? Even if you give me a link to read something, I would really appreciate it. I watched dozens of hours of tutorial on YouTube, but I'm always ready for more.

Of course, I want to share my code, but there is so much, and I'm so new to this, I really don't know where the relevant parts are. In addition, I really want to find out how it all works so that I can help others. If there is such a thing as PM, I will send it to you if you want to take a look. As soon as I earn it, I will post the code here. I have to believe that there are other people who are looking for the same thing as me. However, more importantly, I just want to know, from a high level, how to approach my problem correctly? If you look at my link, you will see that I tried (to pass an integer to the method filling the table), but, as I said, I basically refused this, because I will not go anywhere. People are trying to help me, but I'm an idiot.

Thank you for being with my excruciatingly long message. If you have made it this far and I have suggestions, I’m all ears. I will be honest, though, if you tell me that I just have to give up all this and use the basic data that I will pay. I really don't think I have the time to figure out another way of managing data. As I said, I am very pleased with the database and the request parts of my application - it is just managing the extra looks and transferring data between them that is killing me!

Any help is appreciated - thank you very much.

+7
source share
1 answer

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

How can I pass data between my views ?

Yes, there are eight different links. (Well, this eighth link is a little off topic, but it's pretty close.) There are several ways to do this, and I will briefly review them. I will also describe custom initializers, which are also a good point.

Suppose we create a catalog application that displays a bunch of products in different categories. Imagine that our application opens in a list of products like the Apple Store App. Let's say that when a user clicks on a product, we want to show the product page.

  • You can set properties on the "next" view controller. . We can simply subclass the UIViewController and set the productID property (which we made up). Call our new UIViewController a ProductPageViewController . Here's what it looks like:

     - (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. Call alloc , then init . (The functions are wrapped, that is, we call init directly on the result of the alloc method.)

    Then we set the property of our view. Now the view can be customized in viewWillAppear , and all is well.

  • You can share data through persistent storage. . This method works a little differently. View controllers do not interact at all, except for the first, representing the second. Whenever the value in the first view changes (which you want to save), you write it to Core Data or NSUserDefaults . The new view then reads the value as needed.

    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 } 
  • You can use custom initializers. . This is perhaps the most intuitive way to do this as soon as you understand the concept, because this is the only one where the data is actually “transmitted”, (Unlike method 2, where data is not transmitted directly, and method 1, where data is transferred as a property .)

    Note that in the previous examples, I used the initWithNibName:Bundle method. You may also notice that the UITableViewController uses a different initializer, initWithStyle: These two initializers take some information for the new object so that it knows how to load. First, look at the first:

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

    The first argument tells the view controller that the nib file is to be downloaded. I will now ignore the second argument, since I have never seen anything but nil . Going straight to the second example:

     - (id)initWithStyle:(UITableViewStyle)style; 

    Here you can pass one of two values ​​to a UITableViewStyle . This is one way to determine the style of the table view (another way is to modify the nib file directly).

    Let's say this concept is a bit in our example. Now I'm going to show you how to create your own custom initializer. Let the ProductPageViewController instance be initialized:

     - (id) initWithProductID:(int)productID; 

    It is quite simple. Now we need to implement this method and actually do something with the product identifier. We'll start with the barebones code here to "mimic" the default initializer functionality.

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

    This method will return an initialized copy of our ProductPageViewController , however it will not yet load our user interface from the NIB, or if it was a UITableViewController , it would not set a UITableViewStyle . Let me work with NIB first, and then I will show how to work with UITableViewController . So...

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

    Now. we have an initialized ProductPageViewController loaded from the NIB, but it does nothing yet. Note that we do not expose the NibName and Bundle arguments, but we just pass them ourselves. If you want, you could theoretically expose them. Now take the 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 productID . He can query the database at his discretion and do something with the results. Then you can run different queries based on this productID .

Two additional tips:

  • You might want to pass a few arguments. Of course, you can simply add them to the method - (id) initWithProductID:(int)productID andCategoryID(int)categoryID , but what happens if you have five, six or fifty six (yes, that's a lot) arguments? I would advise passing a collection or an array of arguments.

  • To use custom initializers with a UITableView , you pass a UITableViewStyle instead of a NIB name. Here's what it looks like:

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

When creating my subsections, I suggest a combination of persistent data and user initializers. I also recommend looking at the viewDidLoad and viewWillAppear .

+4
source

All Articles