Reload Content of UITableView - ios

I have a problem with refreshing the content of a UITableView. I'm trying to display a list of members in a UITableView. Above this list I have some kind of dropdown-menu for a group selection. So, if I change the group, selected in the dropdown-menu, I want to change the content of the UITableView underneath it. It's actually not working correctly.
The first time I load the ViewController that contains the UITableView, it shows the correct list of members in the default group. Now, when I change the group, it should display my new list of members, but it doesn't. It seems that the UITableView would not even reload its table content.
Here is my code for the TableViewController:
MemberTableViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.members = [NSMutableArray new];
self.selectedRows = [NSMutableArray new];
self.groupManager = [GroupManager new];
int *number;
if (nil != [self gruppeId]) {
number = [[self gruppeId] intValue]; // Here will be the id of the new selected group
} else {
number = 4010292; // This is just for testing. It's the id of my default group
}
for (Group *group in [self.groupManager findGroupWithID:[NSNumber numberWithInt:number]]) {
for (Member *member in group.member) {
[self.members addObject:member];
}
}
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)];
[self.gruppenMitglieder sortUsingDescriptors:[NSArray arrayWithObject:sort]];
[self.tableView setAllowsMultipleSelection:YES];
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[self members] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GreenTexturedCell *cell = nil;
Member *member = [self members][indexPath.row];
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"GreenTexturedCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]]) {
cell = (GreenTexturedCell*)view;
}
}
cell.textLabel.text = member.name;
cell.textLabel.font = [UIFont fontWithName:#"JandaCloserToFree" size:14.0];
cell.textLabel.textColor = [UIColor whiteColor];
return cell;
}
Now I have another ViewController the MemberListViewController, it contains the MemberTableViewController (I know, the naming is not the best...). The MemberListViewController implements a protocol of the GroupSelectionTableViewController. Its delegate function will be called when the selected group changes. Here is the code for the MemberListViewController:
MemberListViewController.h
#interface MemberListViewController : UIViewController <GroupSelectionDelegate>
#property (weak, nonatomic) IBOutlet UIButton *groupSelection;
#property (nonatomic, strong) GroupSelectionTableViewController *groupTableView;
- (IBAction)groupSelectionPressed:(id)sender;
#end
MemberListViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[self setGroupTableView:[GroupSelectionTableViewController new]];
[[self groupTableView] setDelegate:self];
}
- (IBAction)gruppeAuswahlPressed:(id)sender {
if ([self groupListShown]) {
[[[self groupTableView] view] removeFromSuperview];
[self setGroupListShown:NO];
} else {
[self.view addSubview:[[self groupTableView] view]];
[self setGroupListShown:YES];
}
}
- (void) groupSelectionController:(GroupSelectionTableViewController *)groupSelection DidSelectGroupWithId:(NSString *) groupId {
[[self groupSelection] setTitle:name forState:UIControlStateNormal];
[[[self groupTableView] view] removeFromSuperview];
[self setGroupListShown:NO];
MemberTableViewController *memberTableView = [self.storyboard instantiateViewControllerWithIdentifier:#"memberTable"];
[memberTableView setGroupId:[NSNumber numberWithInt:4017411]]; // Id for testing
[memberTableView refreshControl];
}
Now, if I change the group selection, the -groupSelectionController:DidSelectGroupWithId: Method is called and with [memberTableView refreshControl] I'm able to get into the viewDidLoad Method of the MemberTableViewController again and set the groupId to my testing id. Now i want the TableView to reload its content to get the members of the selected group. With the statement [self.tableView reloadData] I'm getting into the tableView:NumberOfRowsInSection: Method but not into the tableView:CellForRowAtIndexPath: Method and the TableView Content is not redrawn.
What am I doing wrong ?
This problem is driving me nuts, so I hope there's someone to help me out.
Thanks

With instantiateViewControllerWithIdentifier you are creating a new instance of MemberTableViewController, which isn't the one you are showing on screen. Hence, you won't see the changes which should be shown by calling reloadData.
To be able to reload the table data, you can add a link to the table at your MemberListViewController. Change the code of the .h to:
#import "MemberTableViewController.h"
#interface MemberListViewController : UIViewController <GroupSelectionDelegate>
{
IBOutlet MemberTableViewController *memberTableView;
}
#property (weak, nonatomic) IBOutlet UIButton *groupSelection;
#property (nonatomic, strong) GroupSelectionTableViewController *groupTableView;
- (IBAction)groupSelectionPressed:(id)sender;
#end
and then, in the .m, you can call [memberTableView reloadData];
Do not forget to set memberTableView as "new referencing outlet" within the storyboard file.

Related

iOS: How to implement search controller using objective c & How to call API at runtime i.e when I start typing in search controller?

I want to implement search controller like gmail application,
OR I want to implement like this example
Image 1 It shows normal inbox with search controller button
Image 2 After clicking on search button It will expand show like image 2. Here we can enter the words...etc
Image 3 Here whatever we enter, depending upon text it shows in list, and when we click on it, it will navigate to detail view.
same thing I want to implement.
Only thing is that, when I will start typing in search controller, one API will call i.e search, then depending upon text entered in search, it will take as parameter and it will show data in list (table view). this data will come from API response.
And when I click on any result, it has to move detail view.
Anybody, can help me.
I am totally new in iOS. Just now I started learning of iOS. Plz help me for this.
Here is .h file
#import <UIKit/UIKit.h>
#interface PDSearchExampleTableViewController : UITableViewController
{
BOOL searching;
}
#property (strong, nonatomic) UISearchBar *searchBar;
#property (strong, nonatomic) NSMutableArray *sampleDataArray;
#property (strong, nonatomic) NSMutableArray *filteredSampleDataArray;
- (IBAction)searchButtonClicked:(id)sender;
#end
Here is .m file
#import "PDSearchExampleTableViewController.h"
#interface PDSearchExampleTableViewController () <UISearchDisplayDelegate, UISearchBarDelegate>
#end
#implementation PDSearchExampleTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
_searchBar.delegate = self;
_sampleDataArray = [[NSMutableArray alloc] init];
_filteredSampleDataArray = [[NSMutableArray alloc] init];
[_sampleDataArray addObject:#"one"];
[_sampleDataArray addObject:#"two"];
[_sampleDataArray addObject:#"three"];
[_sampleDataArray addObject:#"four"];
[_sampleDataArray addObject:#"five"];
[_sampleDataArray addObject:#"six"];
[_sampleDataArray addObject:#"seven"];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (searching) {
return [_filteredSampleDataArray count];
} else {
return [_sampleDataArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"sampleSearchCell" forIndexPath:indexPath];
if (searching) {
cell.textLabel.text = [_filteredSampleDataArray objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [_sampleDataArray objectAtIndex:indexPath.row];
}
return cell;
}
- (IBAction)searchButtonClicked:(id)sender {
self.navigationItem.rightBarButtonItem = nil;
_searchBar = [[UISearchBar alloc] init];
_searchBar.delegate = self;
_searchBar.placeholder = #"Search Sample Data";
[_searchBar sizeToFit];
self.navigationItem.titleView = _searchBar;
[_searchBar becomeFirstResponder];
[_searchBar.window makeKeyAndVisible];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[_searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searching = NO;
[self.tableView reloadData];
self.navigationItem.titleView = nil;
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(searchButtonClicked:)];
[_searchBar setShowsCancelButton:NO];
[_searchBar resignFirstResponder];
self.navigationItem.rightBarButtonItem = rightBarButton;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
[_filteredSampleDataArray removeAllObjects];
if ([searchText length] != 0) {
searching = YES;
[self searchData];
} else {
searching = NO;
}
[self.tableView reloadData];
}
- (void)searchData {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#", _searchBar.text];
NSArray *tempArray = [_sampleDataArray filteredArrayUsingPredicate:predicate];
NSLog(#"%#", tempArray);
_filteredSampleDataArray = [NSMutableArray arrayWithArray:tempArray];
}
Follow the below steps, it will work definitely not exactly as same as your screenshots.
STEP 1: Create a navigation button on the navigation bar and add image button of a search for it. This can be done by using a storyboard or using programmatically.
Give action to that button,
- (IBAction)searchButtonAction:(id)sender {
SearchViewController *vc=[self.storyboard instantiateViewControllerWithIdentifier:#"id1"];
[self.navigationController pushViewController:vc animated:YES];
}
after clicking this button, it will navigate to SearchViewController view.
See storyboard, design like below image
and write below code in SearchViewController,
Create IBOutlet of textField and give action to the search button, and add tableView and add delegates and data source for it.
#property (weak, nonatomic) IBOutlet UITextField *seachTextField;
#property (weak, nonatomic) IBOutlet UITableView *tableview1;
and
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[_seachTextField resignFirstResponder];
return YES;
}
// This method asks the delegate whether the specified text should be replaced in the text view.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSLog(#"Search String is : %#",_seachTextField.text);
NSString *dataFromSearchTextField=[NSString stringWithFormat:#"%#",_seachTextField.text];
return YES;
}
- (IBAction)searchButtonAction:(id)sender {
// call method for which takes search string
[self ApiMethodCall:_seachTextField.text];
}
//After clicking on search button, below method is called i.e t API is called
-(void)ApiMethodCall:(NSString *)searchText
{
// call your API with parameters
// you will get JSON
}
that's it, now it is your turn. Take data from JSON which may contain arrays and dictionaries. Simply do JSON parsing and write table view data source and delegate methods and show data.
You can follow my blog link . Have implemented in both objective C and Swift.
Swift
Objective C

Further clarification of "How to implement UISearchController with objective c"

I have been trying to implement UISearchController by following stackoverflow thread:
How to implement UISearchController with objective c
and Apples's documentation, but can't make it working. When the initial controller (EVTSearchViewController which is defined as UIViewController) that complies with UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating, UITableViewDelegate
(I needed to make it compliant with UITableViewDelegate too, since I am making it a delegate of the other UITableViewController type EVTSearchResultsViewController *resultsControllers tableView) delegates is presented, I see my .xib with the UISearchBar and UITableView, I click the search bar and start typing:
When I type one letter, search bar disappears and nothing is shown:
First, I do not want the search bar to disappear. Second, updateSearchResultsForSearchController seems not to be called at all since NSLog() set up there does not produce any output when I am typing in the search bar.
I have .xib for the EVTSearchViewController and it has a UISearchBar that I am connecting to the respective property: IBOutlet UISearchBar *searchBar which is then made to point to the UISearchControllers' searchBar:
self.searchBar = self.searchController.searchBar
There is also UITableView that I put below the UISearchBar in the .xib. Another controller that I am using inside EVTSearchViewController is EVTSearchResultsViewController, it is UITableViewController and it does not have its .xib.
Below is the code for viewDidLoad and updateSearchResultsForSearchController methods:
- (void)viewDidLoad
{
_resultsController = [[EVTSearchResultsViewController alloc] init];
_searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsController];
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.placeholder = nil;
[self.searchController.searchBar sizeToFit];
self.searchBar = self.searchController.searchBar;
// we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables
self.resultsController.tableView.delegate = self;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = YES; // default is YES
self.searchController.searchBar.delegate = self; // so we can monitor text changes + others
// Search is now just presenting a view controller. As such, normal view controller
// presentation semantics apply. Namely that presentation will walk up the view controller
// hierarchy until it finds the root view controller or one that defines a presentation context.
//
self.definesPresentationContext = YES; // know where you want UISearchController to be displayed
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
// update the filtered array based on the search text
NSString *searchText = searchController.searchBar.text;
NSLog(#"searchText: %#", searchText);
if (searchText == nil) {
// If empty the search results are the same as the original data
self.searchResults = [[[EVTItemStore sharedStore] allItems] mutableCopy];
} else {
NSMutableArray *searchResults = [[NSMutableArray alloc] init];
NSArray *allEvents = [[EVTItemStore sharedStore] allItems];
NSLog(#"allEvents: %#", allEvents);
for (EVTItem *event in allEvents) {
/*if ([event.number containsString:searchText] || [[phoneMO.closrr_id filteredId] containsString:searchText] || [[phoneMO.contact.fullname lowercaseString] containsString:[searchText lowercaseString]]) {
[searchResults addObject:phoneMO];
}*/
if ([event.eventName containsString:searchText]) {
[searchResults addObject:event];
}
}
self.searchResults = searchResults;
}
// hand over the filtered results to our search results table
EVTSearchResultsViewController *resultsController = (EVTSearchResultsViewController *)self.searchController.searchResultsController;
resultsController.filteredEvents = self.searchResults;
[resultsController.tableView reloadData];
}
The respective #properties defined in EVTSearchViewController:
#interface EVTSearchViewController ()
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
#property (nonatomic, strong) UISearchController *searchController;
#property (nonatomic, strong) EVTSearchResultsViewController *resultsController;
#property (nonatomic, strong) NSMutableArray *searchResults;
// For state restoration
#property BOOL searchControllerWasActive;
#property BOOL searchControllerSearchFieldWasFirstResponder;
#end
Then, here is the code for EVTSearchResultsViewController:
#import "EVTSearchResultsViewController.h"
#implementation EVTSearchResultsViewController
- (instancetype)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:#"UISearchViewCell"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.filteredEvents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"UISearchViewCell"
forIndexPath:indexPath];
cell.textLabel.text = self.filteredEvents[indexPath.row];
return cell;
}
#end
The methods of EVTSearchResultsViewController above are not called at all which makes look very strange for me, why do we need it at all, then?
I tried to set UISearchBar the way Apple docs recommend:
self.resultsTableView.tableHeaderView = self.searchController.searchBar;
but it gives me a non-responsive search box, so when pressing nothing happens.
Could anyone, please, help with resolving the question. The other question linked above can also be clarified then. Thank you.
So, I solved the issue and implemented basic search with UISearchController. Here is what we need to do to implement the basic search:
Create two UITableViewControllers classes with NO .xib files. Yes, there should be no .xib files and we are just creating two classes. In the code below their names are EVTSearchViewController and EVTSearchResultsViewController.
Make one of the controllers to comply with the delegates: <UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating>
Here is the code for the header file of EVTSearchViewController:
#import <UIKit/UIKit.h>
#interface EVTSearchViewController : UITableViewController <UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating>
#end
Here is the EVTSearchResultsViewController's header:
#import <UIKit/UIKit.h>
#interface EVTSearchResultsViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *filteredEvents;
#end
The NSMutableArray *filteredEvents will hold the results of the search. We should NOT implement any of the UITableViewController delegate methods in EVTSearchViewController.m, but should in EVTSearchResultsViewController.m.
Here is the top part of EVTSearchViewController:
#import "EVTSearchViewController.h"
#import "EVTSearchResultsViewController.h"
// Importing the class that stores `EVTItem` object classes
#import "EVTItemStore.h"
#import "EVTItem.h"
#interface EVTSearchViewController ()
#property (nonatomic, strong) UISearchController *searchController;
// We created this class
#property (nonatomic, strong) EVTSearchResultsViewController *resultsController;
// array to hold the results of the search
#property (nonatomic, strong) NSMutableArray *searchResults;
#end
Here is the code for EVTSearchViewController's viewDidLoad: method:
- (void)viewDidLoad
{
[super viewDidLoad];
self.resultsController = [[EVTSearchResultsViewController alloc] init];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsController];
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.placeholder = nil;
[self.searchController.searchBar sizeToFit];
// This line of code is very important. Here we are using apple docs'
// suggestion. UITableViewController has tableView property, so
// we are just setting tableView`s header to apples' UISearchController`s' `searchBar property
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.delegate = self;
// default is YES
self.searchController.dimsBackgroundDuringPresentation = YES;
// so we can monitor text changes + other changes
self.searchController.searchBar.delegate = self;
// know where you want UISearchController to be displayed
self.definesPresentationContext = YES;
}
Then we add to EVTSearchViewController the following method:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
// update filtered array based on the search text
NSString *searchText = searchController.searchBar.text;
if (searchText == nil) {
// If empty the search results should be the same as the original data
self.searchResults = [[[EVTItemStore sharedStore] allItems] mutableCopy];
} else {
NSMutableArray *searchResults = [[NSMutableArray alloc] init];
// [[EVTItemStore sharedStore] allItems] message retrieves
// all of the objects that I have in datastore EVTItemStore
NSArray *allEvents = [[EVTItemStore sharedStore] allItems];
// EVTItem class has a property eventName which we are using
// for searching, then adding it to our searchResults array
for (EVTItem *event in allEvents) {
if ([event.eventName containsString:searchText]) {
[searchResults addObject:event];
}
}
self.searchResults = searchResults;
}
// hand over the filtered results to our search results table
EVTSearchResultsViewController *resultsController = (EVTSearchResultsViewController *)self.searchController.searchResultsController;
resultsController.filteredEvents = self.searchResults;
[resultsController.tableView reloadData];
}
Another controller's EVTSearchResultsViewController #implementation part looks like this:
#implementation EVTSearchResultsViewController
- (instancetype)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.filteredEvents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"UISearchViewCell"
forIndexPath:indexPath];
EVTItem *event = self.filteredEvents[indexPath.row];
cell.textLabel.text = event.eventName;
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:#"UISearchViewCell"];
}
#end
That's it. If we need to further customize our cells, we should be able to do it by making UISearchViewCell.xib for EVTSearchResultsViewController, and using the following viewDidLoad instead:
- (void)viewDidLoad
{
[super viewDidLoad];
// Load the NIB file
UINib *nib = [UINib nibWithNibName:#"UISearchViewCell" bundle:nil];
// Register this NIB which contains the cell
[self.tableView registerNib:nib forCellReuseIdentifier:#"UISearchViewCell"];
}

UISearch Controller Showing data not part of the filtered array

My Question is this. Why is the filtered table view showing rooms, after I start typing in the search bar that are not present when printing the filtered array to the console. I thought it might be that the table view cells are being reused so set the cell label text to nil to ensure the text gets reset in tableviewcellforindex: method , all to no avail. Can anyone help?
This is my Table View Controller that acts as the data source and delegate for for both my standard tableview and filtered tableview
#import <UIKit/UIKit.h>
#import "Rooms.h"
#interface RoomsTableViewController : UITableViewController
<UISearchControllerDelegate,UISearchResultsUpdating,UISearchBarDelegate,UITableViewDelegate>
#property (strong,nonatomic) NSMutableArray *roomList;
#property (strong,nonatomic) NSMutableArray *orderedRoomList;
#property (strong,nonatomic) NSMutableArray *filteredRooms;
#property (strong,nonatomic) UITableViewController *searchResultsController;
#property (strong,nonatomic) UISearchController *searchController;
#end
#import "RoomsTableViewController.h"
#interface RoomsTableViewController ()
#property BOOL searchControllerWasActive;
#property BOOL searchControllerSearchFieldWasFirstResponder;
#end
The implementation file
#implementation RoomsTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
//sort the room list into filetred by alpha numeric A10 before C1 example this will eventually be done on the server
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
}];
self.orderedRoomList = (NSMutableArray*)[self.roomList sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
self.searchResultsController= [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
self.searchController = [[UISearchController alloc]initWithSearchResultsController:self.searchResultsController];
self.searchController.searchResultsUpdater=self;
[self.searchController.searchBar sizeToFit];
self.tableView.tableHeaderView=self.searchController.searchBar;
//set up the data source and delegate of this new table view to be this (roomsTableviewcontroller) view controller
self.searchResultsController.tableView.delegate=self;
self.searchResultsController.tableView.dataSource=self;
self.searchController.delegate=self;
self.searchController.dimsBackgroundDuringPresentation=NO;
self.searchController.searchBar.delegate=self;
self.definesPresentationContext=YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//restore the search controllers active state
if (self.searchControllerWasActive) {
self.searchController.active = self.searchControllerWasActive;
_searchControllerWasActive=NO;
if (self.searchControllerSearchFieldWasFirstResponder) {
[self.searchController.searchBar becomeFirstResponder];
_searchControllerSearchFieldWasFirstResponder=NO;
}
}
}
-(void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
#pragma mark - UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView==self.tableView) {
return [self.orderedRoomList count];
}else{
return [self.filteredRooms count];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 71;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellReuseIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (cell==nil) {
cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
}
Rooms *room = (tableView==self.tableView)? [self.orderedRoomList objectAtIndex:indexPath.row]: [self.filteredRooms objectAtIndex:indexPath.row];
cell.textLabel.text=nil;
NSString *labelString = [NSString stringWithFormat:#"%# %#",room.name,room.roomDescription];
cell.textLabel.text=labelString;
return cell;
}
Below is a photo of the table view in the simulator and a screen print of the check to see if the filtered array has indeed worked correctly as it has. You can see that C3 is not listed as being part of the filtered array but it still appears on screen.

Table View Cell not displaying when Running iOS Simulator

I'm trying to create a table but none of the data I inputted is displaying when I run the simulator. I'm trying to create a simple address book application and So far, here is what I did:
From the empty story board, I added a View Controller from the Object Library then inside the view controller, I added a Table View. Then I embedded the View Controller inside a Navigation Controller. I also added another View Controller in the end to act as a "Details" View.
Inside my viewController.h I added the following code:
#property (strong, nonatomic) NSArray *contact;
#property (strong, nonatomic) NSArray *contactDetails;
#property (nonatomic) NSInteger selectedIndex;
contact is to act as the array that shows all the contacts within the phonebook (This is what I'm having trouble displaying)
contactDetails shows once a user selects a contact.
selectedIndex is my way of telling the application which contact has been selected.
Inside my viewController.m I added the following code:
#import "HWViewController.h"
#interface HWViewController ()
#end
#implementation HWViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.tableView registerClass: [UITableViewCell class] forCellReuseIdentifier:#"Cell"];
self.contact = [[NSArray alloc] initWithArray: [NSArray arrayWithObjects:#"Joe", #"Simon", nil]];
self.contactDetails = [[NSArray alloc] initWithArray: [NSArray arrayWithObjects: #"+689171898057", #"+689173104153", nil]];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.contact.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if(cell==nil){
cell = [[[NSBundle mainBundle] loadNibNamed:#"SampleCell" owner:nil options:nil] objectAtIndex:0];
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 100, 30)];
label.text = [self.contact objectAtIndex:indexPath.row];
[cell.contentView addSubview:label];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
self.selectedIndex = indexPath.row;
[self performSegueWithIdentifier:#"TranslationSegue" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
UIViewController *vc = [segue destinationViewController];
UILabel *details = [[UILabel alloc] initWithFrame:CGRectMake(10, 80, 250, 32)];
details.text = [self.contactDetails objectAtIndex:((HWViewController*)sender).selectedIndex];
[vc.view addSubview:details];
}
#end
After that, I ran the simulation and I get nothing showing up on the table.
you have no cell in the tableview. so add tableview cell in your storyboard
http://www.appcoda.com/customize-table-view-cells-for-uitableview/
Add this in your viewController.h :
#property(nonatomic, strong) IBOUTLET UITableView * TableView;
And then link this outlet to your tableview and then try it out.
And there is no cell in your table view because the prototype cell will be set to zero by default. Now select the tableview go to attribute inspector and set the prototype cell to 1 and then try to run your program with proper cell identifier it will work.
HTH :)
Set tableView delegate and DataSource protocol in you viewdidload method.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.tableView registerClass: [UITableViewCell class] forCellReuseIdentifier:#"Cell"];
self.tableview.delegate = self;
self.tableview.dataSource = self;
self.contact = [[NSArray alloc] initWithArray: [NSArray arrayWithObjects:#"Joe", #"Simon", nil]];
self.contactDetails = [[NSArray alloc] initWithArray: [NSArray arrayWithObjects: #"+689171898057", #"+689173104153", nil]];
}

UITableView content not displayed the very first time even after reloadData

I am trying to create an account page where user will be able to select his preferable language and voice. For this part of my app I was thinking to create 2 different UIButtons and once user has press one of them, a UITableView will appear on appropriate location tableFrame (something like drop down menu). Things were working great, initially, when I had just one array. Now, I have a general array that used from Table View delegate methods to load data and 2 other arrays that contain languages and voices.
My problem is that the very first time when I am tapping on any of the buttons, the table displays no content but numberOfRowsInSection returns correct value. Next, if tap on the same or the other button again .. everything is fine.
I believe the problem appears where I am, initially, initialise the general array with no object in viewDidLoad.
I have tried reloadData with now success.
Any ideas? Below my code:
Account.h
#import <Foundation/Foundation.h>
#interface AccountViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>{
NSMutableArray *content;
NSMutableArray *languages;
NSMutableArray *voices;
CGRect tableFrame;
}
#property (strong, nonatomic) IBOutlet UIButton *languageBtn;
#property (strong, nonatomic) IBOutlet UIButton *narratorBtn;
#property (strong, nonatomic) IBOutlet UITableView *contentTbl;
- (IBAction)selectLanguage:(id)sender;
- (IBAction)selectVoice:(id)sender;
#end
Account.m
- (void) viewDidLoad{
[super viewDidLoad];
content = [[NSMutableArray alloc] init];
languages = [[NSMutableArray alloc] initWithObjects:#"English", #"Ελληνικά", #"French", #"Spanish", #"Deutch", nil];
voices = [[NSMutableArray alloc] initWithObjects:#"English", #"US English", #"Ελληνικά", #"Spanish", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [content count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [content objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)selectLanguage:(id)sender{
if ([(UIButton *)sender tag] == 0) {
content = [languages copy];
tableFrame = CGRectMake(50, 173, 220, 203);
[self startAnimationAndDisplayTable:YES];
[(UIButton *)sender setTag:1];
} else{
[self startAnimationAndDisplayTable:NO];
[(UIButton *)sender setTag:0];
}
}
- (IBAction)selectVoice:(id)sender{
if ([(UIButton *)sender tag] == 0) {
content = [voices copy];
tableFrame = CGRectMake(50, 243, 220, 203);
[self startAnimationAndDisplayTable:YES];
[(UIButton *)sender setTag:1];
} else{
[self startAnimationAndDisplayTable:NO];
[(UIButton *)sender setTag:0];
}
}
- (void)startAnimationAndDisplayTable:(BOOL)show{
if (show) {
[self.contentTbl setHidden:NO];
[self.contentTbl setFrame:tableFrame];
[UIView beginAnimations:#"Fade In" context:nil];
[UIView setAnimationDuration:0.7];
[self.contentTbl setAlpha:1.0];
[UIView commitAnimations];
[self.contentTbl reloadData];
} else{
[UIView beginAnimations:#"Fade Out" context:nil];
[UIView setAnimationDuration:0.5];
[self.contentTbl setAlpha:0.0];
[UIView commitAnimations];
}
}
#end
"content" is an empty mutable array until you touch whatever (button?) action that calls the "selectLanguage" and "selectVoice" methods (and then you reassign the "content" variable).
I don't see any other manipulations of the "content" mutable array, so it's no wonder to me that nothing appears until you actually touch something.
You also do not show where you are calling "reloadData". "content" needs to have array entries in there for "reloadData" to work.

Resources