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];
}
}
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 am new to iOS. I am making an app in which i am getting data from Parse back-end all are working fine.
I did UISearchbar and it works well. But when a search produces more than 6 results (main table have 6 rows, but I search for another Parse class) , this leads to an error.
2015-06-09 14:10:23.318 Aero store[3238:347073] Terminating app due to uncaught exception 'NSRangeException', reason: '
-[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 5]'
This is my code:
#import "CategoryTable.h"
#import "GoodsTable.h"
#import "Parse/Parse.h"
#interface CategoryTable ()<UISearchDisplayDelegate, UISearchBarDelegate>
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic, strong) NSMutableArray *searchResults;
#end
#implementation CategoryTable
#synthesize categoryId;
- (void)viewDidLoad {
[super viewDidLoad];
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.goodsSearchBar contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
[self.searchDisplayController.searchBar setBackgroundImage:[UIImage imageNamed:#"menu-background"]
forBarPosition:0
barMetrics:UIBarMetricsDefault];
CGPoint offset = CGPointMake(0, self.goodsSearchBar.frame.size.height);
self.tableView.contentOffset = offset;
self.searchResults = [NSMutableArray array];
self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent;
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"] != nil) {
//Город установлен - > категории
NSLog(#"Gorod - %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]);
//[self performSegueWithIdentifier:#"showCategory" sender:self];
}
else
{
//Город не установлен -> выбор города
NSLog(#"Gorod - %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]);
}
//Установка лого
UIView *headerView = [[UIView alloc] init];
headerView.frame = CGRectMake(0, 0, 151, 20);
UIImageView *logoImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo"]];
logoImage.frame = CGRectMake(0, 0, 151, 20);
logoImage.contentMode = UIViewContentModeScaleAspectFit;
[headerView addSubview:logoImage];
[self.navigationItem setTitleView:headerView];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.parseClassName = #"Category";
self.pullToRefreshEnabled = NO;
self.paginationEnabled = NO;
}
return self;
}
//Слово для поиска
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
searchString = [searchString lowercaseString];
[self filterResults:searchString];
return NO;
}
//Запрос для поиска
-(void)filterResults:(NSString *)searchTerm {
if (searchTerm.length > 1) {
[PFCloud callFunctionInBackground:#"find"
withParameters:#{#"goodsName": searchTerm, #"city":[[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]}
block:^(NSArray *goodsList, NSError *error) {
if (!error) {
NSLog(#"Найдено: %#",goodsList);
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:goodsList];
dispatch_async(dispatch_get_main_queue(), ^{
[self.searchController.searchResultsTableView reloadData];
});
}
}];
}
}
//Получени списка категорий
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query whereKey:#"cityName" equalTo:[[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"]];
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByAscending:#"createdAt"];
return query;
}
//Количество ячеек для результата поиска
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return self.searchResults.count;
}
else {
return self.objects.count;
}
}
//Обрезка пустых ячеек
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *sectionFooterView = [[UIView alloc] initWithFrame:
CGRectMake(0, 0, tableView.frame.size.width, 1)];
sectionFooterView.backgroundColor = [UIColor clearColor];
return sectionFooterView;
}
//Отрисовка ячеек категорий
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *identifier = #"categoryCell";
PFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if (tableView == self.tableView) {
UILabel *titleLabel = (UILabel*) [cell viewWithTag:200];
titleLabel.text = [object objectForKey:#"title"];
PFFile *thumbnail = [object objectForKey:#"image"];
PFImageView *catImageView = (PFImageView*)[cell viewWithTag:100];
catImageView.image = [UIImage imageNamed:#"placeholder"];
catImageView.file = thumbnail;
[catImageView loadInBackground];
}
else if(tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"test");
PFObject *searchedUser = [self.searchResults objectAtIndex:indexPath.row];
cell.textLabel.text = [[searchedUser objectForKey:#"name"] capitalizedString];
}
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showGoods"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
GoodsTable *goods= segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
categoryId = [object objectForKey:#"title"];
NSLog(#"Category Name = %#", categoryId);
goods.cityName = [[NSUserDefaults standardUserDefaults] objectForKey:#"cityName"];
goods.categoryId = categoryId;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Please help me! I can not solve the problem for several days. :'(
Try
dispatch_async(dispatch_get_main_queue(), ^{
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:goodsList];
[self.searchController.searchResultsTableView reloadData];
});
to ensure editing your datasource and reloading your tablew view are done in the same dispatch queue.
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;
}
I'm using UITextFields as my search bars. I had to do this because I have multiple inputs for people to search for. The search is working perfectly. In fact the text field is working better than a normal search bar memory wise. The only problem is that I cannot select the resulting cell. When I press the cell nothing at all happens. I even put a log statement in didselect and the cell is not even getting the action. Help please.
- (void)viewDidLoad
{
[super viewDidLoad];
self.ASearch.delegate = self;
self.BSearch.delegate = self;
NSAttributedString *str = [[NSAttributedString alloc] initWithString:#"Location" attributes:#{ NSForegroundColorAttributeName : [UIColor blueColor] }];
self.ASearch.attributedPlaceholder = str;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
-(void)viewWillDisappear:(BOOL)animated {
[self dismissKeyboard];
[super viewWillDisappear:animated];
}
-(void)dismissKeyboard {
[ASearch resignFirstResponder];
[BSearch resignFirstResponder];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[Asearch becomeFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 75;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (searchArray.count == 0) {
UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
messageLabel.text = #"Search!";
messageLabel.textColor = [UIColor redColor];
messageLabel.numberOfLines = 0;
messageLabel.textAlignment = NSTextAlignmentCenter;
messageLabel.font = [UIFont fontWithName:#"TimesNewRomanPS-BoldMT" size:20];
[messageLabel sizeToFit];
self.tableView.backgroundView = messageLabel;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
return 0;
} else {
self.tableView.backgroundView = nil;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
return searchArray.count;
}
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
headerView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 90.0, 320.0, 90.0)];
return headerView;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"searchCell";
TopCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
PFObject *searchObject = [searchArray objectAtIndex:indexPath.row];
cell.AImage.image = [UIImage imageNamed:#"DefaultThumbnail"];
cell.AImage.layer.cornerRadius = 5.0f;
cell.AImage.clipsToBounds = YES;
cell.AName.text = [searchObject objectForKey:#"name"];
cell.addressLabel.text = [NSString stringWithFormat:#"%#, %#, %#",[searchObject objectForKey:#"address"],[searchObject objectForKey:#"city"], [searchObject objectForKey:#"state"]];
cell.placeType.text = [searchObject objectForKey:#"name"];
return cell;
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == ASearch) {
NSString *searchString = [NSString stringWithString:placeSearch.text];
searchString = [searchString stringByReplacingCharactersInRange:range withString:string];
[self searchDataBase:searchString];
return YES;
} else {
return NO;
}
}
-(void)searchDataBase: (NSString *)subString {
PFQuery *query = [PFQuery queryWithClassName:#"HotSpots"];
[query whereKey:#"name" matchesRegex:subString modifiers:#"i"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
searchArray = [NSArray arrayWithArray:objects];
[self.tableView reloadData];
NSLog(#"%lu", objects.count);
}];
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
[self dismissKeyboard];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[self searchDataBase:textField.text];
[ASearch resignFirstResponder];
[BSearch resignFirstResponder];
[self dismissKeyboard];
return YES;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier]isEqualToString:#"Segue"]) {
NSIndexPath *indexpath = [self.tableView indexPathForSelectedRow];
HSBarTableViewController *Controller = (HSBarTableViewController *)[segue destinationViewController];
PFObject *pObject = [searchArray objectAtIndex:indexpath.row];
Controller.arObject = pObject;
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"Segue" sender:self];
NSLog(#"Pressed");
}
I have got fully working UISearchDisplayController implied in my UITableView made with Parse.com. Anyway when I put to search for, I always get only results starts with that letter. I want to display every data contains that letter.
For example: I put Om into my search and it searched me only : Oman and Ombudsman . I have in my UITableView also a cell named Community . You see this word also contains om but my search don`t display anything. It displays just words staring with these letters.
Can someone help me? Thank you.
#implementation TableViewController3
#synthesize MainTable;
#synthesize searchBar;
#synthesize searchController;
#synthesize searchResults;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showDetaill"]) {
{
DetailViewController3 *sdvc = (DetailViewController3 *)[segue destinationViewController];
if(self.searchDisplayController.active) {
NSIndexPath *indexPath = [[self tableView] indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
object = (PFObject *)[[self searchResults]objectAtIndex:[[[[self searchDisplayController]searchResultsTableView]indexPathForSelectedRow]row]];
sdvc.objc = object;
} else {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
DetailViewController3 *detailViewController = [segue destinationViewController];
detailViewController.objc = object;
}
}
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
self.tableView.tableHeaderView = self.searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
self.searchResults = [NSMutableArray array];
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
[self.navigationController.navigationBar setBarTintColor:[UIColor lightGrayColor]];
-(void)filterResults:(NSString *)searchTerm {
PFQuery *query = [PFQuery queryWithClassName: #"Countries"];
[query whereKey:#"CountryTitle" hasPrefix:searchTerm];
query.limit = 50;
[query findObjectsInBackgroundWithTarget:self selector:#selector(callbackWithResult:error:)];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterResults:searchString];
return YES;
}
- (void)callbackWithResult:(NSArray *)celebrities error:(NSError *)error
{
if(!error) {
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:celebrities];
[self.searchDisplayController.searchResultsTableView reloadData];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.tableView) {
return self.objects.count;
} else {
return self.searchResults.count;
}
}
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
tableView.rowHeight = 70.0f;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
NSString *uniqueIdentifier = #"MainCell";
CustomCell3 *cell = nil;
cell = (CustomCell3 *) [self.tableView dequeueReusableCellWithIdentifier:uniqueIdentifier];
if (!cell) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"MainCell" owner:nil options:nil];
for (id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[CustomCell3 class]])
{
cell = (CustomCell3 *)currentObject;
break;
}
}
}
if (tableView == self.tableView) {
cell.MainTitle.text = [object objectForKey:#"CountryTitle"];
cell.DescriptTitle.text = [object objectForKey:#"DescriptTitle"];
[cell.FlagTitle setImageWithURL:[NSURL URLWithString:[object objectForKey:#"ImaURL"]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.backgroundView = [[UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"background.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"background.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
}
if(tableView == self.searchDisplayController.searchResultsTableView) {
PFObject *searchedUser = [self.searchResults objectAtIndex:indexPath.row];
NSString *content = [searchedUser objectForKey:#"CountryTitle"];
NSString *desco = [searchedUser objectForKey:#"DescriptTitle"];
cell.DescriptTitle.text = desco;
cell.MainTitle.text = content;
NSString *image = [searchedUser objectForKey:#"ImaURL"];
[cell.FlagTitle setImageWithURL:[NSURL URLWithString:image]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.backgroundView = [[UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"background.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"background.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
}
return cell;
}
#end
Use - (void)whereKey:(NSString *)key containsString:(NSString *)substring instead of - (void)whereKey:(NSString *)key hasPrefix:(NSString *)prefix
-(void)filterResults:(NSString *)searchTerm {
PFQuery *query = [PFQuery queryWithClassName: #"Countries"];
[query whereKey:#"CountryTitle" containsString:searchTerm];
query.limit = 50;
[query findObjectsInBackgroundWithTarget:self selector:#selector(callbackWithResult:error:)];
}
if you use hasPrefix: then the search results will be elements starting with your search string.