In my Parse app, I have Pagination enabled, and for testing purposes, objects per page set to 5. When I run the app I get this in my TableView
1
2
3
4
5
Load More
After clicking Load More the entire table looks like:
1
2
3
4
5
6
7
8
9
10
6
7
8
9
10
Clicking Load More after this will add the set of 11-15 twice. What is going on?
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// The className to query on
self.parseClassName = #"Prayers";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 5;
}
return self;
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:#"Prayers"];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByDescending:#"createdAt"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(PFObject *)object
{
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
self.theObject = object;
BOOL anony = [object[#"Anonymous"] boolValue];
cell.profileName.text = object[#"Title"];
cell.contentLabel.text = object[#"Request"];
cell.firstName = object[#"FirstName"];
cell.lastName = object[#"LastName"];
cell.iostoken = object[#"DeviceID"];
cell.request = object[#"Title"];
cell.prayerObject = object;
PFFile *thumbnail = object[#"ProfilePic"];
cell.profilePic.image = [UIImage imageNamed:#"AppIcon60x60#2x.png"];
/*[cell.commentButton addTarget:self action:#selector(didTapCommentButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.commentButton setTitle:#"Share" forState:UIControlStateNormal];
[cell.commentButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[cell.commentButton setTitleColor:[UIColor greenColor] forState:UIControlStateHighlighted];*/
[thumbnail getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
UIImage *thumbnailImage = [UIImage imageWithData:imageData];
UIImageView *thumbnailImageView = [[UIImageView alloc] initWithImage:thumbnailImage];
cell.profilePic.image = thumbnailImage;
}];
NSString *dates = object[#"dateMade"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM_dd_yyyy"];
NSDate *datefromstring = [formatter dateFromString:dates];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter2 setDateFormat:#"MMM dd, yyyy"];
cell.dateLabel.text = [formatter2 stringFromDate:datefromstring];
UIFont *cellFont = [UIFont fontWithName:#"Verdana-Bold" size:15];
UIFont *cellFont2 = [UIFont fontWithName:#"Verdana-Bold" size:12];
return cell;
}
- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == self.objects.count) {
return nil;
} else {
return [super objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
PFObject *object = [self objectAtIndexPath:indexPath];
if (object == nil) {
// Return a fixed height for the extra ("Load more") row
return 70;
} else {
NSLog(#"%lu", (unsigned long)[self.objects count]);
PFObject *entry = [self.objects objectAtIndex:indexPath.row];
NSString *commentString = entry[#"Request"];
NSString *nameString = #"";
NSLog(#"%#", commentString);
return [Cell heightForCellWithContentString:(NSString *)commentString] +25 ;
}
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == self.objects.count && self.paginationEnabled) {
// Load More Cell
NSLog(#"Load More");
[self loadNextPage];
}
-(PFQuery *)queryForTable {
...
...
...
//Always trigger a network request.
[tableQuery setCachePolicy:kPFCachePolicyNetworkOnly];
//If no objects are loaded in memory, we look to the cache first to fill the table and then subsequently do a query against the network.
if(self.objects.count == 0) {
[tableQuery setCachePolicy: kPFCachePolicyCacheThenNetwork];
}
...
...
...
return tableQuery;
}
Related
NSArray *sectionArray;
int sectionCount=0;
NSDictionary *orderedData;
NSString *checkInStr, *checkOutStr;
NSString *govtTaxes, *enhancementTotal, *grandTotal;
- (void)viewDidLoad {
[super viewDidLoad];
[self setupTable];
[self.bookingsTableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewDidDisappear:(BOOL)animated {
if(doesSendNotification){
NSLog(#"summary view disappeared");
[[NSNotificationCenter defaultCenter] postNotificationName:#"SummaryViewDismissedNotification" object:self];
}
}
-(void)viewWillAppear:(BOOL)animated {
[self.bookingsTableView reloadData];
}
-(void)setupTable {
self.bookingsTableView.rowHeight = UITableViewAutomaticDimension;
self.bookingsTableView.estimatedRowHeight = 50.0;
sectionArray = [[SummaryModel sharedInstance] getTableSections:self.s_sendEnhancementServerDict];
orderedData = [[SummaryModel sharedInstance] getOrderedData:self.s_sendEnhancementServerDict];
[self.bookingsTableView reloadData];
}
#pragma mark- UITableview delegate and datasource methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(section==0){
return 3;
} else if (section>0 && section<(sectionCount-1)){
int rows=(int)[[orderedData objectForKey:(NSString*)[sectionArray objectAtIndex:section]] count];
return rows;
} else {
return 4;
}
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return (NSString*)[sectionArray objectAtIndex:section];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier;
UITableViewCell *cell;
// UITableView *table = (UITableView*)[self.view viewWithTag:11];
if (indexPath.section==0 && indexPath.row>=0 && indexPath.row<=2) {
cellIdentifier =#"SplitCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
UILabel *l1 = (UILabel*)[cell viewWithTag:1];
UILabel *l2 = (UILabel*)[cell viewWithTag:2];
if(indexPath.row==0){
l1.attributedText = [self getStyledString1:#"Hotel Name"];
l2.attributedText = [self getStyledString:self.s_propertyName];
} else if(indexPath.row==1){
l1.attributedText = [self getStyledString1:#"Arrival Date:"];
l2.attributedText = [self getStyledString:checkInStr];
} else if(indexPath.row==2){
l1.attributedText = [self getStyledString1:#"Departure Date:"];
l2.attributedText = [self getStyledString:checkOutStr];
}
} else if (indexPath.section>0 && indexPath.section<(sectionCount-1)) {
// for(int i=0;i<5;i++){
cellIdentifier=#"VerticalLabelCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
UILabel *l3 = (UILabel*)[cell viewWithTag:3];
UILabel *l4 = (UILabel*)[cell viewWithTag:4];
l3.layer.backgroundColor = GOLDEN_COLOR.CGColor;
NSArray *roomTypeArray = [orderedData objectForKey:(NSString*)[sectionArray objectAtIndex:indexPath.section]];
NSDictionary *roomD = [roomTypeArray objectAtIndex:indexPath.row];
NSString *header = [roomD objectForKey:#"room_type_name"];
NSAttributedString *sH = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:#" %#",header] attributes:#{NSFontAttributeName:ARIAL_FONT_BOLD}];
l3.attributedText = sH;
int roomCount = [(NSNumber*)[roomD objectForKey:#"room_units"] intValue];
NSMutableAttributedString *labelText = [[NSMutableAttributedString alloc] init];
for(int i=0;i<roomCount;i++){
NSString *roomNo = [NSString stringWithFormat:#"\n Room # %d\n",i+1];
NSAttributedString *s = [[NSAttributedString alloc] initWithString:roomNo attributes:#{NSFontAttributeName:ARIAL_FONT_BOLD, NSUnderlineStyleAttributeName:#(NSUnderlineStyleSingle)}];
[labelText appendAttributedString:s];
NSString *adults = [NSString stringWithFormat:#" Adults: %# \t\t Max. Adults: %# \n",[roomD objectForKey:#"max_adults"],[roomD objectForKey:#"max_adults"]];
NSAttributedString *s1 = [[NSAttributedString alloc] initWithString:adults attributes:#{NSFontAttributeName:ARIAL_FONT_BOLD}];
[labelText appendAttributedString:s1];
NSArray *enhanc = [(NSArray*)[roomD objectForKey:#"room_features"] objectAtIndex:i];
for(int i=0;i<[enhanc count];i++){
[labelText appendAttributedString:[self getStyledString2:[NSString stringWithFormat:#" %#\n", [enhanc objectAtIndex:i]]]];
}
l4.attributedText = labelText;
}
} else if(indexPath.section==(sectionCount-1)){
cellIdentifier =#"SplitCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
UILabel *l1 = (UILabel*)[cell viewWithTag:1];
UILabel *l2 = (UILabel*)[cell viewWithTag:2];
if(indexPath.row==0){
l1.attributedText = [self getStyledString1:#"Room Charges:"];
l2.attributedText = [self getStyledString:[NSString stringWithFormat:#"£ %#", self.s_priceOfRooms]];
}else if(indexPath.row==1){
l1.attributedText = [self getStyledString1:#"Government Taxes:"];
l2.attributedText = [self getStyledString:[NSString stringWithFormat:#"£ %#", govtTaxes]];
}else if(indexPath.row==2){
l1.attributedText = [self getStyledString1:#"Enhancement Total:"];
l2.attributedText = [self getStyledString:[NSString stringWithFormat:#"£ %#", enhancementTotal]];
}else if(indexPath.row==3){
l1.attributedText = [self getStyledString1:#"Total Charges"];
l2.attributedText = [self getStyledString:[NSString stringWithFormat:#"£ %#", grandTotal]];
}
}
return cell;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
sectionCount = (int)[sectionArray count];
return sectionCount;
}
-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
view.tintColor = GOLDEN_COLOR;
}
-(NSAttributedString*)getStyledString:(NSString*)input {
NSAttributedString *str = [[NSAttributedString alloc] initWithString:input attributes:#{NSForegroundColorAttributeName:GOLDEN_COLOR, NSFontAttributeName:ARIAL_FONT}];
return str;
}
-(NSAttributedString*)getStyledString1:(NSString*)input {
NSAttributedString *str = [[NSAttributedString alloc] initWithString:input attributes:#{NSFontAttributeName:ARIAL_FONT_BOLD}];
return str;
}
-(NSAttributedString*)getStyledString2:(NSString*)input {
NSAttributedString *str = [[NSAttributedString alloc] initWithString:input attributes:#{NSFontAttributeName:ARIAL_FONT}];
return str;
}
I have made a ViewController and added a table view in it. Some data is populated in cells and then displayed.
When I run it, initially I don't see any data in my cells. But when the tableview is scrolled cells start showing the actual data. I don't understand what could be the reason. Any pointers please???
I want to dynamically resize my cells as data can be of random size. Data shows only after scrolling once.
This problem is related to using UITableViewAutomaticDimension and has been reported at other places as well. So this line of code, solved my problem:
-(void)viewDidAppear:(BOOL)animated {
[self.tableView reloadData];
}
This just reloads all the table sections and rows before displaying. So user does not experience blank rows. Refer: http://www.appcoda.com/self-sizing-cells/
You need to use reloadData in the main thread (viewDidLoad). You need to use
dispatch_async like the code below :
dispatch_async(dispatch_get_main_queue(), ^{
[self.mytable reloadData];
}
In setupTable, check sectionArray and orderedData to make sure they're not empty. Add an assertion in setupTable, e.g.,
sectionArray = [[SummaryModel sharedInstance] getTableSections:self.s_sendEnhancementServerDict];
orderedData = [[SummaryModel sharedInstance] getOrderedData:self.s_sendEnhancementServerDict];
NSAssert([sectionArray count] && [orderedData count], #"No data!"); // add this line
[self.bookingsTableView reloadData];
Swift 5+
IOS 13
Xcode 11.2.1 +
Amazing Answer
override func viewDidAppear(_ animated: Bool) {
// self.tablev.frame.origin.y = vnavigation.frame.maxY + 5
// tablevheight = self.tablev.frame.size.height
self.bgview.backgroundColor = UIColor.init(patternImage: UIImage(named: "chat_bg.png")!)
self.registerForKeyboardNotifications()
UIView.performWithoutAnimation {
tablev.beginUpdates()
tablev.endUpdates()
}
}
I have one table view with check mark. when I do check mark one data in my table view my 20,21 data also automatically getting check mark i.e check mark cell reusable.
#interface ViewController ()
{
NSDateFormatter *formatter;
BOOL *check;
}
#property (strong) NSMutableArray *notes;
#end
#implementation ViewController
#synthesize tableView;
#synthesize addButton;
#synthesize catefetchedResultsController;
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.title = #"My Notes";
tableView.dataSource = self;
tableView.delegate = self;
[self.view addSubview:tableView];
formatter = [[NSDateFormatter alloc] init];
formatter.doesRelativeDateFormatting = YES;
formatter.locale = [NSLocale currentLocale];
formatter.dateStyle = NSDateFormatterShortStyle;
formatter.timeStyle = NSDateFormatterNoStyle;
CATransition *animation = [CATransition animation];
[animation setDuration:2.0];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromTop];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
[[addButton layer] addAnimation:animation forKey:#"SwitchToDown"];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Notes"];
NSError *error = nil;
self.notes = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
NSSortDescriptor *titleSorter= [[NSSortDescriptor alloc] initWithKey:#"mod_time" ascending:NO];
[self.notes sortUsingDescriptors:[NSArray arrayWithObject:titleSorter]]
;
NSLog(#"Your Error - %#",error.description);
[tableView reloadData];
}
#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.
return self.notes.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIButton *testButton;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
testButton = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
[testButton setImage:[UIImage imageNamed:#"oval"] forState:UIControlStateNormal];
[testButton setImage:[UIImage imageNamed:#"tick"] forState:UIControlStateSelected];
[testButton addTarget:self action:#selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:testButton];
[cell setIndentationLevel:1];
[cell setIndentationWidth:45];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Configure the cell...
NSManagedObject *note = [self.notes objectAtIndex:indexPath.row];
NSDate *date = [note valueForKey:#"mod_time"];
NSString *dateString = [formatter stringFromDate:date];
cell.textLabel.text = [note valueForKey:#"title"];
cell.detailTextLabel.text = dateString;
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell.textLabel.font = [UIFont fontNamesForFamilyName:#"Avenir"];
cell.textLabel.font = [UIFont fontWithName:#"Avenir" size:19.0];
cell.detailTextLabel.font=[UIFont fontWithName:#"Avenir" size:15.0];
}
-(void)buttonTouched:(id)sender
{
UIButton *btn = (UIButton *)sender;
if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"oval"]])
{
[btn setImage:[UIImage imageNamed:#"tick"] forState:UIControlStateNormal];
}
else
{
[btn setImage:[UIImage imageNamed:#"oval"] forState:UIControlStateNormal];
// other statements
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
//[[_notes objectAtIndex:indexPath.row] checked];
//[tableView reloadData];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// _notes.taskArray[indexPath.row][#"CheckStat"] = #YES
}
- (IBAction)addButtonPressed:(id)sender {
AddNoteViewController *addNoteVC = [AddNoteViewController new];
// to remove unused warning....
#pragma unused (addNoteVC)
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)cTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete object from database
[context deleteObject:[self.notes objectAtIndex:indexPath.row]];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
// Remove device from table view
[self.notes removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (IBAction)btnClick:(id)sender {
}
#end
Every time in cellForRowAtIndexPath: you should get the check state from _notes.taskArray and reset the check mark for the current row.
You can do it by updating the method:
-(void)tableView:(nonnull UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
BOOL currentStatus = [[chekMarkArray objectAtIndex:indexPath.row] boolValue];
[chekMarkArray replaceObjectAtIndex:indexPath.row withObject:#(!currentStatus)];
UIImage *currentImage = nil;
if ([[chekMarkArray objectAtIndex:indexPath.row] intValue]) {
//cell.accessoryType = UITableViewCellAccessoryCheckmark;
currentImage = [UIImage imageNamed:#"check.png"];
}else{
//cell.accessoryType = UITableViewCellAccessoryNone;
currentImage = [UIImage imageNamed:#"uncheck.png"];
}
//yourCell.yourimageView.image = currentImage;//todo
// [tableView reloadData];
}
In my app, I use Parse. I have it set up like this:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// The className to query on
self.parseClassName = #"Prayers";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 20;
}
return self;
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:#"Prayers"];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByDescending:#"createdAt"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(PFObject *)object
{
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
self.theObject = object;
BOOL anony = [object[#"Anonymous"] boolValue];
if (!anony) {
NSString *names = [[object[#"FirstName"] stringByAppendingString:#" "] stringByAppendingString:object[#"LastName"]];
cell.profileName.text = names;
cell.contentLabel.text = object[#"Request"];
cell.firstName = object[#"FirstName"];
cell.lastName = object[#"LastName"];
cell.iostoken = object[#"DeviceID"];
cell.request = names;
cell.prayerObject = object;
PFFile *thumbnail = object[#"ProfilePic"];
cell.profilePic.image = [UIImage imageNamed:#"AppIcon60x60#2x.png"];
/*[cell.commentButton addTarget:self action:#selector(didTapCommentButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.commentButton setTitle:#"Share" forState:UIControlStateNormal];
[cell.commentButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[cell.commentButton setTitleColor:[UIColor greenColor] forState:UIControlStateHighlighted];*/
[thumbnail getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
UIImage *thumbnailImage = [UIImage imageWithData:imageData];
UIImageView *thumbnailImageView = [[UIImageView alloc] initWithImage:thumbnailImage];
cell.profilePic.image = thumbnailImage;
}];
NSString *dates = object[#"dateMade"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM_dd_yyyy"];
NSDate *datefromstring = [formatter dateFromString:dates];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter2 setDateFormat:#"MMM dd, yyyy"];
cell.dateLabel.text = [formatter2 stringFromDate:datefromstring];
UIFont *cellFont = [UIFont fontWithName:#"Verdana-Bold" size:15];
UIFont *cellFont2 = [UIFont fontWithName:#"Verdana-Bold" size:12];
}
else {
// Configure the cell to show todo item with a priority at the bottom
cell.profileName.text = object[#"Title"];
cell.contentLabel.text = object[#"Request"];
cell.firstName = object[#"FirstName"];
cell.lastName = object[#"LastName"];
cell.iostoken = object[#"DeviceID"];
cell.request = object[#"Title"];
cell.prayerObject = object;
PFFile *thumbnail = object[#"ProfilePic"];
cell.profilePic.image = [UIImage imageNamed:#"AppIcon60x60#2x.png"];
[thumbnail getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
UIImage *thumbnailImage = [UIImage imageWithData:imageData];
UIImageView *thumbnailImageView = [[UIImageView alloc] initWithImage:thumbnailImage];
cell.profilePic.image = thumbnailImage;
}];
NSString *dates = object[#"dateMade"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM_dd_yyyy"];
NSDate *datefromstring = [formatter dateFromString:dates];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter2 setDateFormat:#"MMM dd, yyyy"];
cell.dateLabel.text = [formatter2 stringFromDate:datefromstring];
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
PFObject *entry = [self.objects objectAtIndex:indexPath.row];
NSString *commentString = entry[#"Request"];
NSString *nameString = #"";
NSLog(#"%#", commentString);
return [Cell heightForCellWithContentString:(NSString *)commentString] +25 ;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
if (_webViewController2 == nil) {
self.webViewController2 = [[[WebViewController2 alloc] initWithNibName:#"WebViewController2" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController2.entry = entry;
[self.navigationController pushViewController:_webViewController2 animated:YES];
[self.objects objectAtIndex:indexPath.row];
}
else {
PFObject *entry = [self.objects objectAtIndex:indexPath.row];
if (_webViewController == nil) {
self.webViewController = [[[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]] autorelease];
}
_webViewController.finalObject = entry;
[self.navigationController pushViewController:_webViewController animated:YES];
}
#endif
}
As I understand, that should load up 20 items at a time, and when you scroll to the end of those, load up the next 20. However, once I have 20 items, the app crashes, and I get this message:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 20 beyond bounds [0 .. 19]'
After putting an exception breakpoint in, the line causing the error is in the heightForRow method
PFObject *entry = [self.objects objectAtIndex:indexPath.row];
What's going on?
I have a PFQueryTableViewController in my app. If it is a root view of a controller, it is fine. However, if I push it onto another view, there is a strange line that goes through the top of each cell.
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// The className to query on
self.parseClassName = #"Prayers";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 20;
}
return self;
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByDescending:#"createdAt"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(PFObject *)object
{
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
self.theObject = object;
// Configure the cell to show todo item with a priority at the bottom
cell.profileName.text = object[#"Title"];
cell.contentLabel.text = object[#"Request"];
cell.firstName = object[#"FirstName"];
cell.lastName = object[#"LastName"];
cell.iostoken = object[#"DeviceID"];
cell.request = object[#"Title"];
cell.prayerObject = object;
PFFile *thumbnail = object[#"ProfilePic"];
cell.profilePic.image = [UIImage imageNamed:#"AppIcon60x60#2x.png"];
[cell.commentButton addTarget:self action:#selector(didTapCommentButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.commentButton setTitle:#"Share" forState:UIControlStateNormal];
[cell.commentButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[cell.commentButton setTitleColor:[UIColor greenColor] forState:UIControlStateHighlighted];
[thumbnail getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
UIImage *thumbnailImage = [UIImage imageWithData:imageData];
UIImageView *thumbnailImageView = [[UIImageView alloc] initWithImage:thumbnailImage];
cell.profilePic.image = thumbnailImage;
}];
NSString *dates = object[#"dateMade"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM_dd_yyyy"];
NSDate *datefromstring = [formatter dateFromString:dates];
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init];
[formatter2 setDateFormat:#"MMM dd, yyyy"];
cell.dateLabel.text = [formatter2 stringFromDate:datefromstring];
UIFont *cellFont = [UIFont fontWithName:#"Verdana-Bold" size:15];
UIFont *cellFont2 = [UIFont fontWithName:#"Verdana-Bold" size:12];
return cell;
}
Just having this as root view presents this:
If I present it from another view like this:
-(void)myPrayers {
BlogView1 *prayers = [[BlogView1 alloc] init];
[self.navigationController pushViewController:prayers animated:YES];
}
It looks like this:
That looks like a UITableViewCellSeperatorStyle Property needing to be set to UITableViewCellSeparatorStyleNone...
[_table setSeparatorStyle:UITableViewCellSeparatorStyleNone];
OR
set the separator color of your UITableViewCell to clear color
[_table setSeparatorColor:<#(UIColor *)#>]
I am trying to have a custom inset for the separator in a UITableView. Here is my code for viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[ChatTableCell class] forCellReuseIdentifier:#"ChatCell"];
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 65, 0, 0)];
}
The cell separator inset does not work properly as shown in the picture. It works for some cells and does not for others. What am I doing wrong here?
This is what my viewcontroller.m file looks like
#import "ChatListViewController.h"
#interface ChatListViewController ()
#end
#implementation ChatListViewController
- (id)initWithStyle:(UITableViewStyle)style {
//self = [super initWithStyle:style];
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
self.parseClassName = kChatRoomClassKey;
self.paginationEnabled = YES;
self.pullToRefreshEnabled = YES;
self.objectsPerPage = 25;
//[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 65, 0, 0)];
}
return self;
}
- (PFQuery *)queryForTable {
if (![PFUser currentUser]) {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query setLimit:0];
return query;
}
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query whereKey:kChatRoomUsersKey equalTo:[PFUser currentUser]];
[query includeKey:kChatRoomUsersKey];
[query orderByDescending:#"updatedAt"];
[query setCachePolicy:kPFCachePolicyCacheThenNetwork];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
//
// If there is no network connection, we will hit the cache first.
if (self.objects.count == 0 || ![[UIApplication sharedApplication].delegate performSelector:#selector(isParseReachable)]) {
[query setCachePolicy:kPFCachePolicyCacheThenNetwork];
}
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"ChatCell";
ChatTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ChatTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSArray *users = [object objectForKey:kChatRoomUsersKey];
PFUser *cellUser = (PFUser *)[users objectAtIndex:0];
if ([cellUser.objectId isEqualToString:[PFUser currentUser].objectId]) {
cellUser = [users objectAtIndex:1];
NSLog(#"%#", cellUser);
}
cell.textLabel.font = [UIFont fontWithName:kDefaultFontKey size:17.0];
cell.detailTextLabel.font = [UIFont fontWithName:kDefaultFontLightKey size:14];
if ([cellUser isEqual:[NSNull null]]) {
cell.username.text = #"Selfie User";
cell.textLabel.font = [UIFont fontWithName:kDefaultFontKey size:17.0];
cell.latestText.text = [object objectForKey:kChatRoomLatestTextKey];
cell.detailTextLabel.font = [UIFont fontWithName:kDefaultFontKey size:10.0];
[cell.avatarImageView.profileImageView setImage:[UIImage imageNamed:#"AvatarPlaceholder.png"]];
}
else {
cell.username.text = cellUser.username;
cell.textLabel.font = [UIFont fontWithName:kDefaultFontKey size:17.0];
cell.latestText.text = [object objectForKey:kChatRoomLatestTextKey];
cell.detailTextLabel.font = [UIFont fontWithName:kDefaultFontKey size:10.0];
if ([[cellUser fetchIfNeeded] objectForKey:kPAPUserProfilePicSmallKey] == nil) {
[cell.avatarImageView.profileImageView setImage:[UIImage imageNamed:#"AvatarPlaceholder.png"]];
}
else
[cell.avatarImageView setFile:[cellUser objectForKey:kPAPUserProfilePicSmallKey]];
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 70.0f;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PFObject *chatRoomObject = [self.objects objectAtIndex:indexPath.row];
if ([[chatRoomObject objectForKey:kChatRoomReadKey] isEqual:#NO]) {
[chatRoomObject setObject:#YES forKey:kChatRoomReadKey];
[chatRoomObject saveEventually];
UITabBarItem *tabBarItem = [[self.tabBarController.viewControllers objectAtIndex:PAPFriendsTabBarItemIndex] tabBarItem];
NSString *currentBadgeValue = tabBarItem.badgeValue;
if (currentBadgeValue && currentBadgeValue.length > 1) {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSNumber *badgeValue = [numberFormatter numberFromString:currentBadgeValue];
NSNumber *newBadgeValue = [NSNumber numberWithInt:[badgeValue intValue] - 1];
tabBarItem.badgeValue = [numberFormatter stringFromNumber:newBadgeValue];
} else {
tabBarItem.badgeValue = #"";
}
}
ChatViewController *convoVC = [[ChatViewController alloc] init];
NSArray *users = [[self.objects objectAtIndex:indexPath.row] objectForKey:kChatRoomUsersKey];
PFUser *cellUser = (PFUser *)[users objectAtIndex:0];
if ([cellUser.objectId isEqualToString:[PFUser currentUser].objectId]) {
cellUser = [users objectAtIndex:1];
}
[convoVC setUser:cellUser];
[convoVC setChatRoom:[self.objects objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:convoVC animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[ChatTableCell class] forCellReuseIdentifier:#"ChatCell"];
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 65, 0, 0)];
[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];
[self.navigationItem setTitle:#"Chat"];
//Change Back button text
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle: #""
style: UIBarButtonItemStyleBordered
target: nil action: nil];
[self.navigationItem setBackBarButtonItem: backButton];
[self.navigationController setDelegate:self];
}
-(void)viewDidAppear:(BOOL)animated {
[self loadObjects];
//Google Analytics screen tracking
id tracker = [[GAI sharedInstance] defaultTracker];
[tracker set:kGAIScreenName
value:#"Chat"];
[tracker send:[[GAIDictionaryBuilder createScreenView] build]];
}
-(void)viewWillAppear:(BOOL)animated {
[Flurry logEvent:#"Viewed Chat" timed:YES];
}
-(void)viewWillDisappear:(BOOL)animated {
[Flurry endTimedEvent:#"Viewed Chat" withParameters:nil];
}
#end
After all my workaround , now fixed in both ios 7 and 8 tested.
-(void)viewDidLayoutSubviews
{
[customTableview setSeparatorInset:UIEdgeInsetsZero];
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(customCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:#selector(setSeparatorInset:)]){
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:#selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero]; // ios 8 newly added
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}