Obj-C- Datasource for UICollectionView inside of UITableViewCell? - ios

I have a TableView (self.tableView) inside of a ViewController (DashboardViewController). Inside of this tableview, I have a custom cell that contains a UICollectionView.
Everything works fine, however in order to populate the UICollectionView, I'm currently calling data inside my UITableViewCell, which I don't want to do, as every time I scroll up and down, data is called.
Is it possible to make the UICollectionView's datasource an NSMutableArray inside DashboardViewController, instead of having to populate the NSMutableArray inside the UITableViewCell in which it is sitting?
My setup right now:
UITableViewCell.h
#property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
#property (strong, nonatomic) NSMutableArray *clientsWeek;
UITableViewCell.m
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self.collectionView registerNib:[UINib nibWithNibName:#"ClientCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"ClientCollectionViewCell"];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];
NSMutableDictionary *viewParams1 = [NSMutableDictionary new];
[viewParams1 setValue:#"cdata" forKey:#"view_name"];
[DIOSView viewGet:viewParams1 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.clientsWeek = [responseObject mutableCopy];
NSLog(#"The people are here %#", self.clientsWeek);
[self.collectionView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
}

Under the premise that the CellReuseIdentifier is set correctly.
Of course, you can choose to get all the data in DashboardViewController, including the datasource of UICollectionView. Here you need to combine the data. The data source of the tableview must be an array, so the data source of UICollectionView can be placed in the array. Like this
[
{
"UITableViewCellData":{},
"UICollectionViewData":{}
},
...
]
Of course you can also use data model objects to replace.
Then you need to expose a method for receiving the data source to the cell, in which you can refresh your UICollectionView.
UITableViewCell.h
- (void)cellWithDataSource:(NSDictionary *)dataSource;
UITableViewCell.m
- (void)cellWithDataSource:(NSDictionary *)dataSource{
NSDictionary *tableViewDataSource = dataSource[#"UITableViewCellData"];
NSDictionary *collectionViewDataSource = dataSource[#"UICollectionViewData"];
...
}
DashboardViewController passes data to cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellID"];
// first obtains the datasource of each cell, and passes it to each cell
[cell cellWithDataSource:datasource];
return cell;
}

Related

Displaying data on DrawerMenu Tableview

I've been trying to use this repo's sample project on experimenting as passing data between two different view controllers :https://github.com/RajendrasinhParmar/DrawerMenu
I've downloaded the demo code from GitHub and I've been trying to parse this demo JSON with following method:
{
"menu": [
{
"name": "Facebook",
"url": "http://www.facebook.com"
},
{
"name": "Twitter",
"url": "http://www.twitter.com"
}
]
}
#pragma mark - http stuff
- (void)getMenuList {
NSError *error;
NSString *url_string = [NSString stringWithFormat: #"http://json-schema-faker.js.org/#gist/6a6cc18dc58dca786194f390c0af28c9"];
NSData *data = [NSData dataWithContentsOfURL: [NSURL URLWithString:url_string]];
NSMutableDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *menuArray = response[#"menu"];
// NSLog(#"response: %#", response);
for (int i=0; i < menuArray.count; i++) {
NSLog(#"%#", menuArray[i][#"name"]);
NSLog(#"%#", menuArray[i][#"url"]);
}
}
And display "name" in the table view at MenuViewController and pass the url to web view at ViewController when a cell selected.
My problem is. How can i assign name property in Tableview and pass url to webview when selected? I did some searching yet I've failed.
First, create an array property in the interface of your menuViewController and add the table view delegate and data source to your interface declaration. You will also need to add a table view to your menuViewController in interface builder and hook it up to your .h file.
#interface menuViewController:UIViewController <UITableViewDelegate, UITableViewDataSource>
#property(nonatomic) NSArray *menuArray;
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
Next, after getting the JSON serialization, assign to your array defined in interface, then reload your table view
NSMutableDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
self.menuArray=response[#"menu"]; //Assign to array
[self.tableView reloadData];
Now, to setup the table, first assign the datasource and delegate in your viewDidLoad method
- (void)viewDidLoad {
self.tableView.dataSource=self;
self.tableView.delegate=self;
}
Now, implement the table view data source methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//Want as many cells as in array
return self.menuArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"menuCell"];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"defaultCell"];
}
//Display name of current item in array
cell.textLabel.text=[[self.menuArray objectAtIndex:indexPath.row]objectForKey:#"name"];
return cell;
}
Now, you should have your table fully set up with the names displaying. Now to pass url's to next controller, you need to implement another method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Create new controller
ViewController *vc=[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
//Pass it the url
vc.url=[[self.menuArray objectAtIndex:indexPath.row]objectForKey:#"url"];
//Present it
[self presentViewController:vc animated:YES completion:nil];
}
Make menuArray global. Then give number of row count with array count and acces each object with index path, which surly now less then of equal to number of object in table view . Make are property in next view controller with urlString and pass the value from didSelectRowAtIndexPath row (For that purpose you need to subclass you viewController).

How to set height of UITableView to solve scrolling issue?

Background: I'm working on my first iOS app that uses a UITableView for data being loaded dynamically from a web source. No, this is not homework.
Problem: When I scroll down the list bounces back to the top.
Things I've Tried:
This suggestion (reducing the size of the table view) works but now I have large space at the bottom of the screen.
I've tried using [tableView reloadData] but this doesn't changing the behavior. I even hooked this up to a button to make sure it was firing after the view was populated.
I also read a few post about contentSize and how to calculate based on the amount of data loaded in the table. This looks like the solution I need but am having trouble getting a clear explanation of how to implement it for my setup.
Code:
I started a new project with single view application template and added a UITableView to the default view in the main storyboard.
In view controller I have the following (relevant) code:
#interface ERViewController ()
#property (nonatomic, strong) NSMutableArray *myArray;
#property (nonatomic,retain) UITableView *tableView;
#end
#implementation ERViewController
{
NSMutableArray *tableData;
}
Here I am loading the data from Parse.com into my table and then calling [self loadView] to get the view to update after the query finishes.
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *returnedData = [[NSMutableArray alloc] init];
PFQuery *query = [PFQuery queryWithClassName:#"Persons"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
for (PFObject *object in objects) {
//NSLog(#"display name: %#",object[#"firstName"]);
[returnedData addObject:[NSString stringWithFormat:#"%#, %#", object[#"lastName"],object[#"firstName"]]];
}
tableData = returnedData;
// Reload view to display data
[self loadView];
} else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
- (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];
}
// Configure the cell
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
NSArray *itemArray = [NSArray arrayWithObjects: #"✔︎", #"?", #"X", nil];
UISegmentedControl *mainSegment = [[UISegmentedControl alloc] initWithItems:itemArray];
mainSegment.frame = CGRectMake(200,0, 100, 43);
self.navigationItem.titleView = mainSegment;
mainSegment.selectedSegmentIndex = [itemArray count];
[mainSegment addTarget:self
action:#selector(mainSegmentControl:)
forControlEvents: UIControlEventValueChanged];
mainSegment.tag = indexPath.row;
[cell.contentView addSubview:mainSegment];
return cell;
}
Sample screen shot:
Since I'm waiting for the data to load I'm not sure where to resize the view and how exactly I need to resize the view.
You should never ever manually call loadView.
Once you have your tableData call reloadData on the tableView.
You should also load you table data in viewDidAppear:, and if you only want to do it once, create a flag to see if its already been loaded. While waiting for the data to load, tableData will be nil so if you query the count of it, you will be messaging a nil object and therefore it would act like returning 0.
Finally you should not be touching the contentSize of the table view, it handles that itself. You just need to make sure that in Interface Builder, the table view's frame is the same as the root views frame.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSMutableArray *returnedData = [[NSMutableArray alloc] init];
PFQuery *query = [PFQuery queryWithClassName:#"Persons"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
for (PFObject *object in objects) {
//NSLog(#"display name: %#",object[#"firstName"]);
[returnedData addObject:[NSString stringWithFormat:#"%#, %#", object[#"lastName"],object[#"firstName"]]];
}
tableData = returnedData;
// Reload view to display data
[self.tableView reloadData];
} else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
If you just want a UIViewController with only a UITableView in it, consider using a UITableViewController.
Posted for others dealing with the same problem I had and can't just move to a different view controller.
To solve the problem with a UITableView within a general view controller (not UITableViewController) click the little icon below the view controller that looks like this:
The button is titled "Resolve Auto Layout Issues"
Select "Reset to suggested constraints in View Controller"
This fixed all my scrolling issues since I must have been incorrectly snapping to the auto layout edges.

Using UISearchViewController without an underlying UITableView (from a storyboard)

I'm trying to use a UISearchDisplayController to search with CLGeocode as the user types, for use with an MKMapView. My view controller has only two things in it - the UISearchBar associated with the UISearchDisplayController and the map view. I'm using a Storyboard.
Normally one would do this with an underlying table view and would declare a prototype cell there, but there seems to be no way of doing that here since I don't have the table view. So I created a subclass of UITableViewCell called SearchTableViewCell, with associated nib.
The nib contains one label, with this outlet connected:
#interface SearchTableViewCell : UITableViewCell
#property (unsafe_unretained, nonatomic) IBOutlet UILabel *textLabel;
#end
I load the nib in viewDidLoad:
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"SearchTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"CellIdentifier"];
I get the data from CLGeocoder like this:
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self.geocoder geocodeAddressString:searchString completionHandler:^(NSArray *placemarks, NSError *error) {
self.placemarks = placemarks;
[self.searchDisplayController.searchResultsTableView reloadData];
}];
return NO;
}
And my tableview code looks like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.placemarks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = #"CellIdentifier";
SearchTableViewCell *cell = (SearchTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kCellID forIndexPath:indexPath];
CLPlacemark *placemark = self.placemarks[indexPath.row];
NSString *addressString = CFBridgingRelease(CFBridgingRetain(ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)));
cell.textLabel.text = addressString;
return cell;
}
The search part is working - when I get to cellForRowAtIndexPath there is data in self.placemarks. However, the line that dequeues a new cell is failing with an exception the first time it's called:
'NSUnknownKeyException', reason: '[<NSObject 0x1a840d40> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key textLabel.'
My cell object is compliant for textLabel, but I'm wondering about that NSObject there in the error message - is the object being returned not a SearchTableViewCell? It is configured in IB to use the correct class. And why is the dequeue method checking for textLabel anyway? I'm pretty sure I've had custom table cells before that had no textLabel field.
Any suggestions on where I've gone wrong?
It turned out that somehow, I had two connections to textLabel - one proper one to the IBOutlet and another to File's Owner. That must have been how the NSObject was getting returned.
After fixing that, I was getting an assertion failure in -[NSLayoutConstraint constant]. Just on a whim I turned off AutoLayout in the nib, which didn't seem to need it and presto. it works now.

Phone Call within Table Cell

Im writing an app where someone adds a contact to the app, giving their name, number and photo. Then this information is displayed in a table, with each individual contact on a different cell and when the user presses on the cell it will call the number that was typed in for the contact. I have put in a large button on each of the cells for the user to press. This is the code
PictureListMainTable.m
#import "PictureListMainTable.h"
#import "PictureListDetail.h"
#import "CoreDataHelper.h"
#import "Pictures.h"
#implementation PictureListMainTable
#synthesize managedObjectContext, pictureListData, callButton;
// When the view reappears, read new data for table
- (void)viewWillAppear:(BOOL)animated
{
// Repopulate the array with new table data
[self readDataForTable];
}
// Grab data for table - this will be used whenever the list appears or reappears after an add/edit
- (void)readDataForTable
{
// Grab the data
pictureListData = [CoreDataHelper getObjectsForEntity:#"Pictures" withSortKey:#"title" andSortAscending:YES andContext:managedObjectContext];
// Force table refresh
[self.tableView reloadData];
}
#pragma mark - Actions
// Button to log out of app (dismiss the modal view!)
- (IBAction)logoutButtonPressed:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark - Segue methods
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get a reference to our detail view
PictureListDetail *pld = (PictureListDetail *)[segue destinationViewController];
// Pass the managed object context to the destination view controller
pld.managedObjectContext = managedObjectContext;
// If we are editing a picture we need to pass some stuff, so check the segue title first
if ([[segue identifier] isEqualToString:#"EditPicture"])
{
// Get the row we selected to view
NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];
// Pass the picture object from the table that we want to view
pld.currentPicture = [pictureListData objectAtIndex:selectedIndex];
}
}
#pragma mark - Table view data source
// Return the number of sections in the table
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// Return the number of rows in the section (the amount of items in our array)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [pictureListData count];
}
// Create / reuse a table cell and configure it for display
- (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];
}
// Get the core data object we need to use to populate this table cell
Pictures *currentCell = [pictureListData objectAtIndex:indexPath.row];
// Fill in the cell contents
cell.textLabel.text = [currentCell title];
cell.detailTextLabel.text = [currentCell desc];
int number;
number = [currentCell desc];
-(IBAction)MakePhoneCall:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:",number]];
}
// If a picture exists then use it
if ([currentCell smallPicture])
{
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
cell.imageView.image = [UIImage imageWithData:[currentCell smallPicture]];
}
else{
}
return cell;
}
// Swipe to delete has been used. Remove the table item
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Get a reference to the table item in our data array
Pictures *itemToDelete = [self.pictureListData objectAtIndex:indexPath.row];
// Delete the item in Core Data
[self.managedObjectContext deleteObject:itemToDelete];
// Remove the item from our array
[pictureListData removeObjectAtIndex:indexPath.row];
// Commit the deletion in core data
NSError *error;
if (![self.managedObjectContext save:&error])
NSLog(#"Failed to delete picture item with error: %#", [error domain]);
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
-(IBAction)MakePhoneCall:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:",number]];
}
#end
PictureListMainTable.h
#import <UIKit/UIKit.h>
#interface PictureListMainTable : UITableViewController
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) NSMutableArray *pictureListData;
#property (nonatomic, retain) IBOutlet UIButton *callButton;
-(IBAction)MakePhoneCall:(id)sender;
- (void)readDataForTable;
#end
Where should I place the IBaction and why isint it working at the moment where it is and how can I make it work?
There are a couple of approaches you could take to achieve this. But firstly, I don't understand what you are doing at the bottom of -tableview:cellForRowAtIndexPath:. It's as if you are trying to define your IBAction method inside this method. You also have it defined at the bottom of the implementation, but in that method the number variable is not in scope.
Anyway, you should subclass the UITableViewCell. In the implementation for the subclass, you should define the IBAction method and hook it up in interface builder, or otherwise.
When the button is tapped, you should hand the number for the selected cell back to the PictureListMainTable view controller, in order for that view controller to process it (i.e. call the number). You can do this in two ways:
1) the delegate method
Create a protocol, defined in the header file for your subclass of UITableViewCell. And make the main view controller conform to this protocol. Set the cell's delegate to the main view controller. In the implementation of the cell subclass, call this delegate method. For example:
the header file for the UITableViewCell subclass "PictureListMainTableCell.h"
#protocol PictureListMainTableCellDelegate;
#interface PictureListMainTableCell : UITableViewCell
#property (nonatomic, copy) NSString *telephoneNumber;
#property (nonatomic, weak) id<PictureListMainTableCellDelegate> delegate;
#end
#protocol PictureListMainTableCellDelegate
-(void)pictureListMainTableCell:(PictureListMainTableCell *)cell wantsToCallNumber:(NSString *)number;
#end
the implementation file "PictureListMainTableCell.m"
#import "PictureListMainTableCell.h"
#implementation PictureListMainTableCell
-(IBAction)MakePhoneCall:(id)sender
{
//send the delegate the number to call.
[self.delegate pictureListMainTableCell:self wantsToCallNumber:self.telephoneNumber];
}
#end
Above, in the MakePhoneCall method, we call -pictureListMainTableCell:wantsToCallNumber: on the delegate. In this case, the delegate is your main view controller. We will set this below.
Setting the cell's delegate: In your main view controller file (PictureListMainTable.m), in the -tableView:cellForRowAtIndexPath: method, set the delegate on the cell to self. e.g.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// get the cell...
PictureListMainTableCell *cell = // dequeue the cell
// do some other setting up...
// set the delegate on the cell
cell.delegate = self;
// set the telephoneNumber variable on the cell, for example...
cell.telephoneNumber = [currentCell desc];
return cell;
}
Now you need to make sure self implements the delegate method. So still in PictureListMainTable.m, you need to define the method as follows:
#pragma mark - PictureListMainTableCellDelegate methods
-(void)pictureListMainTableCell:(PictureListMainTableCell *)cell wantsToCallNumber:(NSString *)number
{
NSString *urlString = [NSString stringWithFormat:#"tel://%#", number];
NSLog(#"calling telephone number [%#]", number);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}
You should also specify that the PictureListMainTable class conforms to your new protocol, as well as the UITableViewDataSource protocol. Add a private category on PictureListMainTable as follows (at the top of the implementation file, after the imports, before #implementation):
#interface PictureListMainTable () <UITableViewDataSource, PictureListMainTableCellDelegate>
#end
(this extends the PictureListMainTable interface. It only extends it to specify privately that it conforms to these protocols.)
2) the NSNotification method
While I was typing out the above explanation, I decided it's my preferred way of doing things, so I would recommend doing it like that. There is the option of posting an NSNotification form your cell subclass, and observing for this notification from your main view controller. Just look into NSNotificationCenter, the following methods:
–postNotificationName:object:userInfo: (send the number in userInfo dictionary). Listen for it using –addObserver:selector:name:object:.
But like I said, option 1 is better, in my opinion.
Let me know if anything is unclear, good luck :)
EDIT: I really recommend reading this blog post to understand delegation: http://alexefish.com/post/15966868557/understanding-and-creating-delegates-in-objective-c

iOS - UIViewController, UITableView, UIScrollView and UISegmentedControl - oh my

So, simply put, I have the following setup:
UIViewController - this is the main, parentController
Within this main view, I have a UIScrollView at the very top, and a UITableView below it.
The UITableView is populated with core data via NSFetchedResultsController...
UIScrollView (The UIViewController is the delegate of this UIScrollView)
|- Within this, I have 2 UIViews that I show: 1 contains a UISegmentedControl, the other just contains nothing but UILabels
When the segmentedControl's value changes (ie: A user clicks on it), I just want to reload the UITableView's list of rows by issuing a new fetchRequest (by just changing the predicate and refetching) to the NSFetchedResultsController.
However, that's exactly where I began having an issue.
Whenever I issue [tableView reloadData], the top-most UIScrollView (not the UITableView's ScrollView, but the extra one I added to the UIViewController) stop responding.
Before I ever issue [tableView reloadData], scrolling works just fine. After I issue it, the scrollView stops responding, and scrolling stops completely.
I've tried all of the following:
[self.topScrollView setScrollingEnabled:YES]
self.topScrollView.delegate = self;
[self.topScrollView setContentSize:CGSizeMake(640.0f, self.topScrollView.frame.size.height)];
[self.topScrollView setContentOffset:CGPointMake(0, 0)];
I removed the UISegmentedControl completely. What I did instead was put a button at the very top of the view, and just issued [tableView reloadData];. It is when the tableView is reloaded, that the UIScrollView stops responding.
Is this a bug? Am I completely missing something here? The only thing I can even begin to think of is that the UITableView inherits from UIScrollView, and so that when the table reloads, it must be doing something to cause the topScrollView to either lose all sense of contentOffset/Size and/or its delegate or something...
Has anyone ever tried this? Has anyone ever had this issue?
The only way I could solve this was by creating a ContainerView, splitting the header out into its own UIViewController, and then setting that UIViewController as the UIVScrolLView delegate and just handling the entire header there.
While this works - I'm kind of confused, and would really like to know if a better alternative exists...
Edit: Here is a basic code example of what I was doing before I split it out the header into a ContainerView and just loaded it via embededSegue:
-(void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.topScrollView setContentSize:CGSizeMake(640.0f, self.topScrollView.frame.size.height)];
[self.topScrollView setContentOffset:CGPointMake(0, 0)];
}
// .....
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"listItemCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Load the cell with what is in core data at this index path..
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
#pragma mark SegmentedControl Switch
- (IBAction)segmentedControlValueChanged {
NSFetchRequest *aRequest = [[self fetchedResultsController] fetchRequest];
NSPredicate *predicate;
switch(self.segmentedControl.selectedSegmentIndex) {
case 0:
predicate = [NSPredicate predicateWithFormat:#"status = %#", #"incomplete"];
break;
case 1:
predicate = [NSPredicate predicateWithFormat:#"status = %#", #"complete"];
break;
case 2:
predicate = [NSPredicate predicateWithFormat:#"status = %#", #"deleted"];
break;
default:
predicate = [NSPredicate predicateWithFormat:#"status = %#", #"none"];
break;
}
[aRequest setPredicate:predicate];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[self.tableView reloadData];
// self.topScrollView.delegate = self;
// [self.topScrollView setContentSize:CGSizeMake(640.0f, self.topScrollView.frame.size.height)];
// [self.topScrollView setContentOffset:CGPointMake(0, 0)];
// [self.topScrollView setScrollEnabled:YES];
}

Resources