iOS todo-tutorial, can't repopulate tableview - ios

So yesterday i began learning iOS programming, and i followed the tutorial for the to-do app.https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/SecondTutorial.html#//apple_ref/doc/uid/TP40011343-CH8-SW1
I have created my own tablelistviewcontroller as the guide tells me, and all my previous static data is gone when i boot, and the tutorial tells me this
you’ll notice that it implements three methods—numberOfSectionsInTableView:, tableView:numberOfRowsInSection:, and tableView:cellForRowAtIndexPath:. You can get your static data to display again by commenting out the implementations of these methods. Go ahead and try that out if you like.
So i commented out the cellForRowAtIndexPath, it was the only one commented out. And then i got an error at the "reuseIdentifier", so after a time of googling, i have managed to name my cells "Cells" and i ended up with this code,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cells";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
But everytime i build and start the app, i cant see my previous data, i can see it in my storyboard, but not in app.. And now i am out of ideas and since i am a newbie i believe the solution is pretty easy.
Please notify if you need any additional data.

I think you really misunderstood these lines:
So why doesn’t your data show up? Table views have two ways of getting
data—statically or dynamically. When a table view’s controller
implements the required UITableViewDataSource methods, the table view
asks its view controller for data to display, regardless of whether
static data has been configured in Interface Builder. If you look at
XYZToDoListTableViewController.m, you’ll notice that it implements
three methods—numberOfSectionsInTableView:,
tableView:numberOfRowsInSection:, and
tableView:cellForRowAtIndexPath:. You can get your static data to
display again by commenting out the implementations of these methods.
Go ahead and try that out if you like.
The thing is when you are adding data using your app, the data is no more static. It is dynamic. UITableView doesn't store your data. It just displays it. And when you are using dynamic data, you will need a datasource which will give the tableView the data to display. You must store the data by some possible storage mechanisms in IOS. Here is a link to one such tutorial which will get you started with Core Data.
Here is a good tutorial which will get you started with UITableView that will display a dynamic data.
The problem is you got the concept totally wrong.
EDIT
You might have added something like <UITableViewDataSource> in the interface file and may have added the ViewController as the datasource for the table(either using ctrl-drag in story board or tableView.datasource = self; in the code). Just remove these two and your static content will display again.

Related

No data at all is showing in UITableView

I have created numerous Xcode projects to see if this was a single project problem but no. The problem that I am getting is that when I populate a UITableVIiew with either local data or data that is stored in a Parse database it does not show.
I have tried re-installing Xcode, cleaning my project and walking through the code/project to see if I'd made a mistake but everything looks in place.
An example is that I created a UITableViewController with a UIImage in the cell and when I build and run the project it does not show up.
Here is an example:
Thanks in advance.
You should implement two required methods of UITableViewDataSource.
Something like that:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
return cell;
}
This would go quicker if you just posted the available code... Annnnyway...
The reason I ask is because if you've only done this in storyboard, and it's a dynamic table, the table looks to your numberOfRowsInSection method to see if it should be populating the table or not. If this is 0, then you'll get no rows no matter what you put into the storyboard.
Also, if you've got a cell identifier of cell in your cellForRowAtIndexPath, but you haven't identified your storyboard cell as cell, then you'll still get blank cells.
Furthermore, if you have implemented these two methods correctly, you need to ensure that this table is hooked up to that class as it's dataSource, either via storyboard or programatically.
But these are all just guesses because I would need to see code to figure it out.
If you are using a UITableViewController, have you changed the cells to static?
You said you don't have any custom code other than what Xcode provides. That is your problem.
You need to implement the UITableViewDataSource methods in order to install your data into your table view. Xcode does not do that. The code Xcode puts into your view controller tells the table view that there is no data. You need to report that there is at least 1 section, and at least 1 row in that section. You then need to write code for cellForRowAtIndexPath that installs data from your model into your cells.
Nikita lists 2 of the 3 methods that you must implement before you table view will do anything.

How to create a repeatable view in iOS and XCode

I am somewhat new to iOS, but am experienced in Android.
I have an app I am working on and it needs to populate a page with your "history" of past people you've interacted with, and it shows their picture, name, rating, and some other information.
This needs to populate in a vertical list, maybe a table? See the image below...
Now, in android, I would create a custom class with a layout that houses the picture, name, information, rating, and what not in one xml file, and in the activity I would call that class in a for loop, grabbing all the users and then programmatically it would add each view one after another, with their own unique user information until there is no more users to populate with.
How exactly can I do this in iOS and xcode? Do I need to make an XIB and add the picture, name, rating, and info place holders in that, and create a custom class for it that I would use to run in a for loop as well? I am a little stuck on how to do this with iOS.
Any help is much appreciated, and I can provide any additional information! Thanks :)
In iOS, you probably want to use a UITableView, with each row being a custom subclass of UITableViewCell. You can either create the layout for those cells in a separate XIB, or put the whole lot, tableView and "prototype" cells in a storyboard. You can achieve a lot without even subclassing, so fire up a dummy project in XCode and play (using one of Apple's templates gives you a good start). Enjoy.
What you probably want is to use a UITableView.
You don’t do the for-loop yourself. What you do is implement a set of delegate methods that the table view calls back to.
You can create your prototype cell in your XIB or Storyboard. When you add a Table View to the layout, you can then add a cell to that table view, and that cell will be your prototype. It looks like you only need one prototype cell, but you can create as many as you need. In Interface Builder you give the prototype cell a “reuse identifier”, which is just an arbitrary tag you use to refer to the prototype in your code. Your prototype cell can be your own subclass of UITableViewCell, or if you don’t need any custom code in it, you can just use UITableViewCell.
Then you implement several delegate methods. One is where you set the number of sections in the table view; it looks like you will only have on section.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv
{
return 1;
}
Then you tell it how many items are in the table view. Assuming you have the objects you want to display in an array, you just return the length of the array.
- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section
{
return self.objects.count;
}
Then, for each item in the array, cellForRowAtIndexPath will be called. Make that method return the actual cell. You call dequeueReusableCellWithIdentifier to retrieve your prototype cell, using the reuse identifier you assigned in Interface Builder. Then use the corresponding object to set up the UI elements in your cell.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)i
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:i];
Thingy *item = self.objects[i.row];
cell.textLabel.text = item.name;
return cell;
}
That should be enough to get you started with the documentation, now that you have the overview of what you need to implement.
The first thing you have to do in switching from Android to iOS is to learn the terminology. Then you'll know what to search for on Google, SO, etc.
What's you're looking to do is create a UITableView.
Here is a link to a super basic 'how-to' to get you started with tableviews.
http://www.appcoda.com/uitableview-tutorial-storyboard-xcode5/
Once you've got the basics down, you'll want to take that a step further with learning how to customize the UITableViewCell within your tableview, so you can accomplish the look you've detailed in the question.
http://www.appcoda.com/customize-table-view-cells-for-uitableview/
I'm not sure I can help anymore than that at the moment. Jump in, learn tableviews, and start searching on OS to answer the million other questions you'll have a long the way.
Good luck!

how to fix an issue with custom subclass of uitableviewcell reuse?

Before I get crucified for this, let me state... Yes, I have read every "relevant" answer on this topic and have not found a workable solution. Most "correct" answers are pre-ARC and discuss "releasing" a cell, which just isn't done anymore. Secondly, my problem is not "global", meaning some views have no problems, while others do. So here is my question...
I have sub-classed uitableviewcell and setup some uilabels & custom uiviews. From there I wired everything up in ib (Xcode 5.x iOS 7.x). Once I put in the appropriate code and create the tableview & dynamic cells from a nsarray "not mutable" everything works exactly as expected with no issues.
This is the fun part. I am making changes to allow the data source of the tableview, which is an nsarray to be mutable to allow adding and removing of items / cells. This is where things get hairy. When I start to add more objects to the array and when the reuse cell is being put on screen visual data from old cells is being reused on new cells. I say "visual" because once the cell is selected the view updates to display the correct information. The part that is interesting is that as I stated I have some uilabels which never have any problems being redisplayed, my custom views however are now the piece of the puzzle that is displaying info from past cells, and when scrolling back up, the original cells no longer display the correct information. Once the cell is tapped, then the cell updates and displays the correct information.
the most confusing bit of this is that before my array was mutable and had a static amount of objects this worked fine. Even if a cell went off screen and came back, it was still the correct information being displayed. Now I know that shouldn't have anything to do with it, but it is strange that it worked using the same tableview & cell code that I am using now.
I have tried adding in
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (!cell) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"]; // note: obviously as stated, tacking on "autorelease" here as mention in other suggestions is not going to work.
}
Which doesn't fix the issue.
I tried overriding the "prepareForReuse" method on my custom cell subclass and that does not resolve the issue either. I have made the views, "strong" & "weak", and all that and still every 3rd or so cell gets repeated with garbage data until it is refreshed. Again, the uilabels which are setup the same way as the views have no problems and data is never reused. I would say there is a problem with my custom views, but setting up the table from a static source of identical information there is no problem.
I would like to post some code, but it's all pretty generic code for tableviews & delegates. any suggestions would be greatly appreciated.
As i said the code is all pretty generic, but apparently it needs posing anyway so here it is..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyThing *thing = self.stuffArray[indexPath.row];
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.thisLabel.text = thing.someText;
cell.thatLabel.text = thing.otherText;
cell.view1.someProptery = thing.object1.property
cell.view2.someProptery = thing.object2.property
cell.view3.someProptery = thing.object3.property
//"someProperty" on "view..." is an NSInt that is used to determine custom drawing in the view.
return cell;
}
I think the key to the solution lies in your comment about the custom views in the cells. If cellForRowAtIndexPath is altering the states of those views, they need to know that they must be redrawn, so you'll need to augment the synthesized setter in your custom view.m that has someProperty.
If the someProperty determines how this view get's drawn, then it's incumbent upon the setter to indicate that the view is out of date....
- (void)setSomeProperty:(NSInteger)someInt {
_someProperty = someInt;
[self setNeedsDisplay];
}

IOS 7 DateCell example with a XIB

I have looked through Apple's DateCell example, unfortunately as all other examples I found it is based on a storyboard. I am trying to create a simple TableViewController with two cells, one for showing the selected date and another for showing a date picker.The Controller will be connected to a bigger app which does not use storyboards. Can somebody write a short guidelines how to recreate the TableView from Apple's example as a XIB and a few sentences regarding the implementation?
Thank you in advance!
After making a sufficient research on the topic, I managed to build a solution out of two separate tutorials.
My main problem were the dynamic prototype cells used in the storyboard example provided by Apple. Therefore I created a customised cell with UIDatePicker inside. I used this tutorial to customise the cell xib file according to my needs and then used it in the UITableView.
Afterwards I followed this tutorial, only instead of a storyboard I created a UITableViewController and used the custom cell with UIDatePicker inside. This example seemed much easier to follow than the sample code provided by Apple.
I didn't encounter any other problems on the way, but if you have any questions I would gladly try to answer. I am still quite new to iOS and Objective-C, so maybe three is a better and easier solution out there.
First of all you need to create two custom cells (one for selected date, second for picker), which both are subclasses of UITableViewCell.
You also need to create two xib files for them. Then change the class of xib to our custom class and connect outlets. Next import that classes to your UITableViewController. In method viewDidLoad write something:
UINib *customNib = [UINib nibWithNibName:#"CustomNibName" bundle:nil];
[self.tableView registerNib:customNib forCellReuseIdentifier:#"CustomCellIdentifier"];
After that you can use your cells in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method:
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCellIdentifier" forIndexPath:indexPath];

Xcode 4.5 UITableView

I have a question regarding UITableView on Xcode. I have text in the cell but when I test it, it doesn't show. I just started programming so any help would be appreciated. If anyone can email me so I can provide the project file that would be most helpful.
You will need to be aware of how table views work. I would suggest carefully reading some of the excellent online documentation on this topic, including sample code if available.
You will need to remember that the system is responsible for deciding which parts of the table view are supposed to be visible, then asking your code to provide the details of what should be seen.
If you have actually provided the routine to provide the contents of the cell, try putting in a breakpoint or some logging to ensure that your code is being called. If so, start by returning something simple and verifying that this is displayed.
Also, prepare code with an explanation of what it is doing to add to the question. You never know, just doing that may clarify to you what is going wrong. If not, post it up and give someone else a chance to help you.
I cannot really directly solve your problem because you surprisingly haven't given code so as far as I know you could be missing a semicolon! (JK)
This is a detailed answer I gave to someone a while ago, very relevant to your situation
But for a table view use this code:
- (UITableViewCell *)tableView:(UITableView *)tableView2 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"UITableViewCell"]
autorelease];
cell.textLabel.text = nil;
}
if (cell) {
//customization
cell.textLabel.text = #"Text Label";
}
return cell;
}
You say you are starting coding.... let me explain. First of try picking up the book:
The Big Nerd Ranch Guide
I suggest you read a heck load of books to get you juiced up on language and API and programming skills
Dequeuing is basically nilling and cacheing any cell that is not visible, aka you scroll past it. Therefore, cell == nil will be called in probably four situations (that I can think of):
When we first setup the table view (cells will be nil)
When we reload data
Whenever we may arrive at this class
When the cells becomes invisible from the table view
So, the identifier for dequeuing is like an ID. Then in the statement to see if cell is nil, we initialize cell, you can see the overridden init method: initWithStyle. This is just what type of cell there is, there are different types with different variables you can customize. I showed you the default. Then we use the reuseIdentifier which was the dequeuing identifier we said earlier. THEY MUST MATCH! I nil textLabel just for better structure, in this case each cell has the same text so it won't matter really. It makes it so the cell that dequeues comes back with the right customization you implemented. Then once cell is actually valid, we can customize.
Also, you are using the same text for each cell. If you do want to have different text for each cell, familiar yourself with NSArray. Then you could provide the array count in numberOfRowsForSection and then do something like this:
cell.textLabel.text = [array objectAtIndex: [indexPath row]];
Where indexPath is the NSIndexPath argument provided in the cellForRowAtIndexPath method. The row variable is the row number, so everything fits!
Wow, that was a lot to take in right! Now go stop being an objective-c noob and start reading some books!
For more info read:
Table View Apple Documentation

Resources