the code below not being called.
Header File
#import "SASlideMenuViewController.h"
#import "SASlideMenuDataSource.h"
#import "SASlideMenuDelegate.h"
#import "spHomeViewController.h"
#import <UIKit/UIKit.h>
#import "UIColor+CustomColor.h"
#interface spMenuViewController : SASlideMenuViewController<SASlideMenuDataSource,SASlideMenuDelegate, UITableViewDataSource>
#property NSMutableArray *menuArray;
#end
#import "spMenuViewController.h"
#interface spMenuViewController ()<SASlideMenuDataSource,SASlideMenuDelegate, UITableViewDataSource>
#property (nonatomic) CGFloat selectedHue;
#property (nonatomic) CGFloat selectedBrightness;
#end
#implementation spMenuViewController
#synthesize selectedHue;
#synthesize selectedBrightness;
-(id) initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]) {
self.selectedBrightness = 0.3;
self.selectedHue = 0.0;
}
return self;
}
-(void)tap:(id)sender{
}
-(void) viewDidLoad{
[super viewDidLoad];
}
-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return YES;
}
-(void)viewDidAppear:(BOOL)animated{
[self.tableView reloadData];
}
#pragma mark -
#pragma mark SASlideMenuDataSource
-(void) prepareForSwitchToContentViewController:(UINavigationController *)content{
UIViewController* controller = [content.viewControllers objectAtIndex:0];
if ([controller isKindOfClass:[spHomeViewController class]]) {
spHomeViewController* coloredViewController = (spHomeViewController*) controller;
}
}
// It configure the menu button. The beahviour of the button should not be modified
-(void) configureMenuButton:(UIButton *)menuButton{
menuButton.frame = CGRectMake(0, 0, 40, 29);
[menuButton setImage:[UIImage imageNamed:#"menuicon"] forState:UIControlStateNormal];
}
// It configure the right menu button. The beahviour of the button should not be modified
-(void) configureRightMenuButton:(UIButton *)menuButton{
menuButton.frame = CGRectMake(0, 0, 40, 29);
[menuButton setImage:[UIImage imageNamed:#"menuiconright"] forState:UIControlStateNormal];
}
// This is the segue you want visibile when the controller is loaded the first time
-(NSIndexPath*) selectedIndexPath{
return [NSIndexPath indexPathForRow:0 inSection:0];
}
// It maps each indexPath to the segueId to be used. The segue is performed only the first time the controller needs to loaded, subsequent switch to the content controller will use the already loaded controller
-(NSString*) segueIdForIndexPath:(NSIndexPath *)indexPath{
NSString* result;
switch (indexPath.section) {
case 0:
result = #"segueHome";
break;
case 1:
result = #"segueHome";
break;
default:
result = #"segueHome";
break;
}
return result;
}
-(Boolean) disableContentViewControllerCachingForIndexPath:(NSIndexPath *)indexPath{
return YES;
}
-(Boolean) hasRightMenuForIndexPath:(NSIndexPath *)indexPath{
return YES;
}
#pragma mark -
#pragma mark UITableViewDataSource
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 3;
}
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (section == 0) {
return #"Red";
}else if (section == 1){
return #"Green";
}else {
return #"Blue";
}
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 4;
}
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat brightness = 1-((double) indexPath.row)/5;
NSInteger section = indexPath.section;
CGFloat hue=0;
if (section == 0) {
hue = 0.0;
}else if (section==1){
hue = 0.33;
}else if (section==2){
hue = 0.66;
}
cell.backgroundColor = [UIColor colorWithHue:hue saturation:1.0 brightness:brightness alpha:1.0];
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:#"item"];
return cell;
}
-(CGFloat) leftMenuVisibleWidth{
return 260;
}
-(CGFloat) rightMenuVisibleWidth{
return 260;
}
//restricts pan gesture interation to 50px on the left and right of the view.
-(Boolean) shouldRespondToGesture:(UIGestureRecognizer*) gesture forIndexPath:(NSIndexPath*)indexPath {
CGPoint touchPosition = [gesture locationInView:self.view];
return (touchPosition.x < 50.0 || touchPosition.x > self.view.bounds.size.width - 50.0f);
}
#pragma mark -
#pragma mark UITableViewDelegate
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat brightness = 1-((double) indexPath.row)/5;
NSInteger section = indexPath.section;
CGFloat hue=0;
if (section == 0) {
hue = 0.0;
}else if (section==1){
hue = 0.33;
}else if (section==2){
hue = 0.66;
}
self.selectedHue = hue;
self.selectedBrightness = brightness;
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
#pragma mark -
#pragma mark SASlideMenuDelegate
-(void) slideMenuWillSlideIn:(UINavigationController *)selectedContent{
NSLog(#"slideMenuWillSlideIn");
}
-(void) slideMenuDidSlideIn:(UINavigationController *)selectedContent{
NSLog(#"slideMenuDidSlideIn");
}
-(void) slideMenuWillSlideToSide:(UINavigationController *)selectedContent{
NSLog(#"slideMenuWillSlideToSide");
}
-(void) slideMenuDidSlideToSide:(UINavigationController *)selectedContent{
NSLog(#"slideMenuDidSlideToSide");
}
-(void) slideMenuWillSlideOut:(UINavigationController *)selectedContent{
NSLog(#"slideMenuWillSlideOut");
}
-(void) slideMenuDidSlideOut:(UINavigationController *)selectedContent{
NSLog(#"slideMenuDidSlideOut");
}
-(void) slideMenuWillSlideToLeft:(UINavigationController *)selectedContent{
NSLog(#"slideMenuWillSlideToLeft");
}
-(void) slideMenuDidSlideToLeft:(UINavigationController *)selectedContent{
NSLog(#"slideMenuDidSlideToLeft");
}
#end
Did you make SASlideMenuViewController as datasource of the UITableView ?
Check the code :
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.dataSource = self;
}
or connecting File's owner as a datasource of your table view in Xib.
I think you just set UITableView.dataSource but not UITableView.delegate. Set it in your xib.
and you should implement the method below:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
and it must return a positive number.
Related
updated my .h and .m files. As mentioned i have to get the data (plist
file) from the ViewController1 tableview once rows (multiple) have
been selected to the tableview in the second view controller. Here i struggle mostly since days :)
#import "ViewController1.h"
#interface UIViewController () <UITableViewDataSource, UITableViewDelegate> #end
#implementation ViewController1 {
NSArray *tableData; }
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"TableData" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:path];
tableData = [dictionary objectForKey:#"Cupcakes"];}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tableData count]; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#end
import "ViewController.h"
#import "SWRevealViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize count;
#synthesize countLabel;
#synthesize negative;
- (void)viewDidLoad
{
negative = TRUE;
[super viewDidLoad];
_barButton.target = self.revealViewController;
_barButton.action = #selector(revealToggle:);
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
#pragma mark - TableView Deletage and Datasouce methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
}
}
- (IBAction)plus:(UIButton*)sender{
count++;
[self displayCount];
}
- (IBAction)minus:(UIButton*)sender {
count--;
if (negative){ //This simply checks if negative mode is offsw_rear
if (count < 0){ //and if count is negative
count = 0; //sets it back to zero
}}
[self displayCount];
}
- (void)displayCount {
[self.countLabel setText:[[NSString alloc]initWithFormat:#"%ld", (long)self.count]];
}
- (UIViewAnimationOptions) closeAnimationCurve {
return UIViewAnimationOptionCurveEaseOut;
}
// Enabling Deepnes on left menu
- (BOOL)deepnessForLeftMenu
{
return YES;
}
// Enabling Deepnes on left menu
- (BOOL)deepnessForRightMenu
{
return YES;
}
// Enabling darkness while left menu is opening
- (CGFloat)maxDarknessWhileLeftMenu
{
return 0.50;
}
// Enabling darkness while right menu is opening
- (CGFloat)maxDarknessWhileRightMenu
{
return 0.5;
}
#end
Suppose, you have made multiple selections in your main Table.
Then using [mainTable indexPathsForSelectedRows]; will give the indexPaths of the selected cells.
Before you go to next View Controller, pass a array containing selected cells using :
1.) Create a new array in which you loop through these indexPath.row and get the elements from cupcakes Array.
NSMutableArray *selectedCellArray = [[NSMutableArray alloc] init];
for(NSIndexPath *index in [mainTable indexPathsForSelectedRows])
{
[selectedCellArray addObject: cupcakes[index.row]];
}
2.) Pass this to your next View Controller by creating a array property in it.
viewController.tableArray = selectedCellArray;
In my app I have a popup with a [table view][1] .
When compiled with Xcode 5.1 everything works fine, but the same code compiled with Xcode 6.1 failed to call the [cellForRowAtIndexPath][3] [delegate][4] method.
The other delegate meths are called.
One intersting point is self.tableView.rowHeight; returns -1
I have tried explicitly setting the delegate and data source to self but that makes not difference
The class is called by the following code;
`-(IBAction)selectLanguage:(id)sender
{
ATLMLanguagePopoverTableViewController *pvc = [[ATLMLanguagePopoverTableViewController alloc] initWithNibName:nil bundle:nil];
pvc.target = self;
pvc.action = #selector(popoverDidSelectItem:);
pvc.items = [[[ATLMLibraryManager getManager]libraryDefaults]getAvailableLanguageNames];
_myPopoverController.contentViewController = pvc;
[_myPopoverController setPopoverContentSize:[pvc popoverContentSize]];
[_myPopoverController presentPopoverFromBarButtonItem:(UIBarButtonItem *)sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
`
Hear is the definition of the class
/
/ LanguagePopoverTableViewController.m
// SalesAid
//
// Created by phuang on 1/16/13.
// Copyright (c) 2013 Align Technology. All rights reserved.
//
#import "ATLMLanguagePopoverTableViewController.h"
#import "ATLMLocalizationManager.h"
#import "ATLMUtils.h"
#interface ATLMLanguagePopoverTableViewController ()
#end
#implementation ATLMLanguagePopoverTableViewController
#synthesize items, selectedItem, target, action;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
selectedItem = -1;
target = nil;
action = NULL;
}
return self;
}
-(void) resetLocalization {
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)setItems:(NSArray *)newItems {
items = [newItems copy];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
selectedItem=0;
NSString *curLang = (NSString *) [[ATLMLocalizationManager getManager]getCurrentLanguage] ;
for(int i = 0; i < items.count ; i++ ){
if([curLang isEqualToString:(NSString *)[items objectAtIndex:i]]){
selectedItem = i;
break;
}
}
NSIndexPath *i = [NSIndexPath indexPathForRow:selectedItem inSection:0];
[self.tableView selectRowAtIndexPath:i animated:NO scrollPosition:UITableViewScrollPositionNone];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (CGSize)popoverContentSize {
NSInteger rowHeight = self.tableView.rowHeight;
UITableView *tv = self.tableView;
rowHeight = 50;
return CGSizeMake(100, [items count] * rowHeight);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [items 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.font = [UIFont systemFontOfSize:14];
UIView *myBackView = [[UIView alloc] initWithFrame:cell.frame];
myBackView.backgroundColor = [ATLMUtils getAlignBlue];
cell.selectedBackgroundView = myBackView;
[cell setSelectedBackgroundView: myBackView ];
NSString *textLabelKey = [items objectAtIndex:[indexPath indexAtPosition:1]];
cell.textLabel.text = ATLMLocalizedString(textLabelKey, nil);
cell.textLabel.textAlignment = NSTextAlignmentCenter;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedItem = indexPath.row;
if (target != nil && action != NULL) {
[target performSelector:action withObject:self];
}
}
#end
`
OK to answer my own question;
Basically the code adds the model to the view controller after the init method is called. However is seem the thread model has changed a bit and the view is created before the model is added so the row count in the model is zero
The solution is to pass the model as part of the init method.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil items:(NSArray *)itemArray
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
items = [itemArray copy];
selectedItem = -1;
target = nil;
action = nil;
}
return self;
}
I need the UISearchBar to always stay inside the NavigationBar. But so far self.searchDisplayController.displaysSearchBarInNavigationBar = YES; is not doing it. When I first start the app the searchBar is inside the NavigationBar. But as soon as I click on it, it smacks itself right in the middle of my scene/screen and never leaves.
This question is a follow up to How do I add storyboard-based Header and CustomTableCell to a “Search Bar and Search Display Controller”
My .h file is
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate>
#end
and my .m file is
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic,strong)NSMutableArray *data;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
self.data=[[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [_data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.textLabel.text = [NSString stringWithFormat:#"Row %d", indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"Row %d: %#", indexPath.row, [_data objectAtIndex:indexPath.row]];
return cell;
}
#pragma mark - delegate
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(mockSearch:) userInfo:searchString repeats:NO];
return NO;
}
- (void)mockSearch:(NSTimer*)timer
{
[_data removeAllObjects];
int count = 1 + random() % 20;
for (int i = 0; i < count; i++) {
[_data addObject:timer.userInfo];
}
[self.searchDisplayController.searchResultsTableView reloadData];
}
#end
And that’s the entire program.
I am trying to resize a section header, according to a selection in the headers UISegmentedControl.
For some reason, it just doesn't want to work. I have tried with [self.tableView beginUpdates]; and [self.tableView endUpdates]; before, around and after the change-height code.. but it just act weird.
I get it to hide and show content, but it seems to allocate a different height for the view even thought the size of the header should be less.
This is what happens:
https://dl.dropboxusercontent.com/u/3077127/Problem3.mov
This is my code:
typedef enum {
kSearchTypeFrom = 0,
kSearchTypeTo
} kSearchType;
#interface MainVC ()
#property (nonatomic, strong) FilterVC *filterView;
#property (nonatomic, assign) kSearchType searchType;
#end
#implementation MainVC
#synthesize filterView = _filterView;
#synthesize searchType = _searchType;
[...]
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.searchType = kSearchTypeFrom;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
// Configure the cell...
[cell.detailTextLabel setText:#"Test"];
return cell;
}
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (!self.filterView) {
self.filterView = [[FilterVC alloc] init];
[self.filterView.view setBackgroundColor:self.navigationController.navigationBar.barTintColor];
}
[self.filterView.segment setSelectedSegmentIndex:self.searchType];
[self.filterView.segment addTarget:self action:#selector(didChangeSegmentSelection:) forControlEvents:UIControlEventValueChanged];
return self.filterView.view;
}
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.searchType == kSearchTypeFrom)
{
return 130;
}
else {
return 100;
}
}
#pragma mark - Height change table section
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
[self.tableView endUpdates];
[self.filterView.view needsUpdateConstraints];
}
[...]
The FilterVC class is nothing more than an UIViewController containing the following:
#import "InsetTextField.h"
#interface FilterVC : UIViewController
#property (nonatomic, strong) IBOutlet InsetTextField *amountField;
#property (nonatomic, strong) IBOutlet UISegmentedControl *segment;
#property (nonatomic, strong) IBOutlet UIButton *fromButton;
#property (nonatomic, strong) IBOutlet UILabel *changeToText;
#property (nonatomic, strong) IBOutlet UIButton *changeToButton;
#end
What is it that I am doing wrong?
As an alternate to trying to animate, you could try reloading the table using the following:
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
//[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
//[self.tableView endUpdates];
[self.tableView reloadData];
[self.filterView.view needsUpdateConstraints];
}
EDIT:
How about a variable to track height? This is sloppy code, but if the concept works, you can refactor it:
// Declare a variable
#proprty (strong, nonatomic) float headerHeight;
// Use that variable for defining the height
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.searchType == kSearchTypeFrom)
{
headerHeight = 130;
}
else {
headerHeight = 100;
}
return headerHeight
}
Then change that variable:
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
// Change the variable used for the header height
if (self.searchType == kSearchTypeFrom)
{
headerHeight = 130;
}
else {
headerHeight = 100;
}
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
[self.tableView endUpdates];
[self.filterView.view needsUpdateConstraints];
}
This question already has answers here:
UITableView cells strangely disappearing
(2 answers)
Closed 9 years ago.
Very strange problem here.
Essentially what is happening is that our Tableview cells are becoming hidden in some cases when we simply put the app to sleep and then re-unlock. Our normal tableview looks like this:
And then when we re-open the app it will look like this:
All the rows and sections are set correctly, yet the cells are hidden.:
When this happens, our cellForRowAtIndexPath no longer gets called. This surely has to be the problem. Has anyone ever seen behavior like this? Here is how we set up the tableview. (sorry it is long)
//
// SPHomeViewController.m
// Spek
#interface SPHomeViewController () <UITableViewDataSource, UITableViewDelegate, MKMapViewDelegate, SPCreationViewDelegate, UIAlertViewDelegate, CLLocationManagerDelegate>
#property (nonatomic, strong) UITableView* tableView;
#property (nonatomic, strong) NSMutableArray* tableDatasource;
#property (nonatomic, strong) NSMutableArray* datasource;
#property (nonatomic, strong) NSMutableArray* friendsDatasource;
#property (nonatomic, strong) UISegmentedControl* userFilterSegment;
#property (nonatomic) BOOL isLoadingData;
#end
#implementation SPHomeViewController
#synthesize datasource = _datasource;
#synthesize friendsDatasource = _friendsDatasource;
#synthesize tableDatasource = _tableDatasource;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
//[[SPLocationManager locationManager] startUpdatingLocationForSig];
[self setNeedsStatusBarAppearanceUpdate];
self.view.backgroundColor = [UIColor colorWithRed:230.0f/255.0f green:230.0f/255.0f blue:230.0f/255.0f alpha:1.0];
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - kTopBarHeight)];
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
if (self.creationView.center.y > self.view.frame.size.height) {
self.creationView = nil;
}
NSLog(#"Mem warning");
}
//****************************************
//****************************************
#pragma mark - UITableViewDelegate/DataSource
//****************************************
//****************************************
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"INDEX PATH ROW: %d AND SECTION: %d", indexPath.row, indexPath.section);
if (indexPath.section == 0) {
UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SPMapCellSpace"];
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView = [[UIView alloc] init];
cell.selectedBackgroundView = [[UIView alloc] init];
return cell;
} else if (indexPath.section == self.tableDatasource.count + 1) {
UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SPBottomCellSpace"];
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView = [[UIView alloc] init];
cell.selectedBackgroundView = [[UIView alloc] init];
return cell;
}
SPMark* mark = self.tableDatasource[indexPath.section - 1];
NSString* reuseId = [SPHomeViewController cellIdentifierFromData:mark];
SPTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseId];
if (cell == nil) {
cell = [SPTableViewCell cellFromMark:mark reuseID:reuseId];
[cell updateView:YES];
}
[cell addDataToCell:mark];
if (indexPath.section >= self.tableDatasource.count - 2 && !self.isLoadingData && self.pageNumber != -1) {
self.fetchNextPage = YES; // When the scrollview stops it will load more data if available.
}
return cell;
}
- (unsigned int)getPageNumber {
return (self.userFilterSegment.selectedSegmentIndex == 0) ? self.pageNumber : self.friendsPageNumber;
}
- (void)setCurrentPageNumber:(unsigned int)page {
if (self.userFilterSegment.selectedSegmentIndex == 0) {
self.pageNumber = page;
} else {
self.friendsPageNumber = page;
}
}
- (void)incrementCurrentPageNumber {
if (self.userFilterSegment.selectedSegmentIndex == 0) {
self.pageNumber++;
} else {
self.friendsPageNumber++;
}
}
// Every cell has a section header so this should be equal to the number of speks returned from the server
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#"section count is: %d",self.tableDatasource.count + 2 );
return self.tableDatasource.count + 2; // Add two because the mapview needs to go on the top and extra spacing at the bottom.
}
// There is a section for every cell, so there is only one cell per section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return kMapHeight+2;
} else if (indexPath.section == self.tableDatasource.count + 1) {
return kExtraSpaceBelowHomeView;
}
SPMark* mark = self.tableDatasource[indexPath.section - 1];
return [SPTableViewCell cellHeightForMark:mark];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 || indexPath.section == self.tableDatasource.count + 1) {
cell.backgroundColor = [UIColor clearColor];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 || indexPath.section == self.tableDatasource.count + 1)
return;
SPMark* mark = self.datasource[indexPath.section - 1 ];
SPMarkViewController* markVC = [SPMarkViewController withMark:mark];
[markVC displayData];
[self.navigationController pushViewController:markVC animated:YES];
}
-(void)reloadTableview {
[self.tableView setDelegate:self];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[self.tableView setNeedsDisplay];
});
}
- (void)showNoItems {
if (self.tableDatasource.count == 0 && self.accuracyBad == NO) {
self.opaqueIcon.hidden = NO;
self.noItems.hidden = NO;
self.beTheFirst.hidden = NO;
self.downArrow.hidden = NO;
self.noItemsBackround.hidden = NO;
[self.view bringSubviewToFront:self.noItemsBackround];
[self.view bringSubviewToFront:self.downArrow];
[self.view bringSubviewToFront:self.beTheFirst];
[self.view bringSubviewToFront:self.noItems];
[self.view bringSubviewToFront:self.opaqueIcon];
}
}
- (void)showTableView {
if (self.tableDatasource.count != 0) {
self.noItems.hidden = YES;
self.beTheFirst.hidden = YES;
self.downArrow.hidden = YES;
self.noItemsBackround.hidden = YES;
self.opaqueIcon.hidden = YES;
[self.view sendSubviewToBack:self.noItemsBackround];
[self.view sendSubviewToBack:self.downArrow];
[self.view sendSubviewToBack:self.beTheFirst];
[self.view sendSubviewToBack:self.noItems];
[self.view sendSubviewToBack:self.opaqueIcon];
}
}
//****************************************
//****************************************
#pragma mark - Setters/Getters
//****************************************
//****************************************
- (NSMutableArray*)datasource {
if (!_datasource) {
_datasource = [NSMutableArray array];
if (!self.firstLoad) {
[self loadDataForPagination:NO];
}
}
return _datasource;
}
- (NSMutableArray*)friendsDatasource {
if (!_friendsDatasource) {
_friendsDatasource = [NSMutableArray array];
if (!self.firstLoad) {
[self loadDataForPagination:NO];
}
}
return _friendsDatasource;
}
- (NSMutableArray*)tableDatasource {
if (!_tableDatasource) {
_tableDatasource = (self.userFilterSegment.selectedSegmentIndex == 0) ? self.datasource : self.friendsDatasource;
}
return _tableDatasource;
}
- (SPCreationView*)creationView {
if (!_creationView) {
UIView* window = [SPUtils getAppDelegate].window;
CGSize viewSize = window.frame.size;
CGRect startFrame = CGRectMake(0, viewSize.height, [SPUtils screenWidth], [SPUtils screenHeight]);
_creationView = [SPCreationView creationView:startFrame delegate:self];
[window insertSubview:_creationView belowSubview:self.creationButton];
_creationView.frame = startFrame;
}
return _creationView;
}
- (void)setTableDatasource:(NSMutableArray *)tableDatasource {
_tableDatasource = tableDatasource;
[self preFetchImages];
dispatch_async(dispatch_get_main_queue(), ^{
if(_tableDatasource == nil || _tableDatasource.count == 0) {
[self showNoItems];
} else {
[self showTableView];
}
[self reloadTableview];
});
}
- (void)setDatasource:(NSMutableArray *)datasource {
_datasource = datasource;
}
- (void)setFriendsDatasource:(NSMutableArray *)friendsDatasource {
_friendsDatasource = friendsDatasource;
}
#end
If you think it's a AppDelegate problem, we don't do anything with this controller in there, so I don't see how it could be.
I've only seen this occur previously when I was reloading data (incorrectly) from a background thread. I see you're trying to push the reloads onto the main thread already.
It looks like you're flailing a bit trying to be sure updates are occurring on the main thread. You should probably just verify that your actions are occurring on main by checking [NSThread isMainThread] rather than making your code async to the main thread, making lots of async flow changes can lead to unexpected behavior.
That said, since this only happens on wake from sleep maybe you have some background mode on and you aren't updating the UI from the correct thread there?