I am currently working on a socket based application in which I have to change color of UIlabel inside custom UITableView cell on the basis of comparing previous value of label with current value received from socket.
I take two string variables also in custom cell to check previous and current value.
Here is cellFor row at index path code...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MWCell *mwCell=(MWCell*)[tableView dequeueReusableCellWithIdentifier:#"mwCellIdentifier"];
if (mwCell==nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:#"MWCell" owner:self options:nil];
for (id temp in topLevelObjects) {
if ([temp isKindOfClass:[MWCell class]]) {
mwCell=(MWCell*)temp;
}
}
}
NSDictionary *tempDic=[watchScriptArray objectAtIndex:indexPath.row];
if ([[tempDic valueForKey:#"expirydate"] valueForKey:#"text"]) {
mwCell.companyName.text=[NSString stringWithFormat:#"%#-%#",[[tempDic valueForKey:#"symbolname"] valueForKey:#"text"],[[tempDic valueForKey:#"expirydate"] valueForKey:#"text"]];
}else{
mwCell.companyName.text=[NSString stringWithFormat:#"%#",[[tempDic valueForKey:#"symbolname"] valueForKey:#"text"]];
}
[mwCell.companyName setTextColor:t.formfgColor];
[mwCell.companyName setShadowColor:t.formShadowColor];
if (![mwCell.buyRate.text isEqualToString:#""]) {
float preVal=[mwCell.prev_br floatValue];
float nxtVal=[[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"] floatValue];
if (nxtVal>preVal) {
[mwCell.buyRate setBackgroundColor:t.socketHighbgColor];
mwCell.buyRate.textColor=t.socketHighfgColor;
}
if (nxtVal<preVal){
[mwCell.buyRate setBackgroundColor:t.socketLowbgColor];
mwCell.buyRate.textColor=t.socketLowfgColor;
}
}else{
[mwCell.buyRate setBackgroundColor:t.socketNormalbgColor];
mwCell.buyRate.textColor=t.socketNormalfgColor;
}
if (![mwCell.sellRate.text isEqualToString:#""]) {
float preVal=[mwCell.sellRate.text floatValue];
float nxtVal=[[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"] floatValue];
if (nxtVal>preVal) {
[mwCell.sellRate setBackgroundColor:t.socketHighbgColor];
[mwCell.sellRate setTextColor:t.socketHighfgColor];
}
if (nxtVal<preVal) {
[mwCell.sellRate setBackgroundColor:t.socketLowbgColor];
[mwCell.sellRate setTextColor:t.socketLowfgColor];
}
}else{
[mwCell.sellRate setBackgroundColor:t.socketNormalbgColor];
mwCell.sellRate.textColor=t.socketNormalfgColor;
}
mwCell.buyRate.textAlignment=NSTextAlignmentCenter;
mwCell.sellRate.textAlignment=NSTextAlignmentCenter;
mwCell.buyRate.text=[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"];
mwCell.sellRate.text=[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"];
mwCell.prev_br=[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"];
mwCell.pre_sr=[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"];
[mwCell.buyRate setShadowOffset:CGSizeMake(0, 0)];
[mwCell.sellRate setShadowOffset:CGSizeMake(0, 0)];
if ([mwCell.buyRate.text floatValue]<0) {
[mwCell.buyRate setBackgroundColor:t.socketLowbgColor];
[mwCell.buyRate setTextColor:t.socketLowfgColor];
}
if ([mwCell.sellRate.text floatValue]<0) {
[mwCell.sellRate setBackgroundColor:t.socketLowbgColor];
[mwCell.sellRate setTextColor:t.socketLowfgColor];
}
return mwCell;
}
I have change my code to check with previous array values with current array values instead of checking current array with text in cell.But this also doesn't seems to work properly.On scrolling it fills other row color also.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MWCell *mwCell=(MWCell*)[tableView dequeueReusableCellWithIdentifier:#"mwCellIdentifier"];
if (mwCell==nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:#"MWCell" owner:self options:nil];
for (id temp in topLevelObjects) {
if ([temp isKindOfClass:[MWCell class]]) {
mwCell=(MWCell*)temp;
mwCell.buyRate.backgroundColor=[UIColor whiteColor];
mwCell.sellRate.backgroundColor=[UIColor whiteColor];
mwCell.buyRate.textColor=[UIColor blackColor];
mwCell.sellRate.textColor=[UIColor blackColor];
}
}
}
NSDictionary *tempDic=[watchScriptArray objectAtIndex:indexPath.row];
NSDictionary *prevDict=[prevScriptArray objectAtIndex:indexPath.row];
if ([[tempDic valueForKey:#"expirydate"] valueForKey:#"text"]) {
mwCell.companyName.text=[NSString stringWithFormat:#"%#-%#",[[tempDic valueForKey:#"symbolname"] valueForKey:#"text"],[[tempDic valueForKey:#"expirydate"] valueForKey:#"text"]];
}else{
mwCell.companyName.text=[NSString stringWithFormat:#"%#",[[tempDic valueForKey:#"symbolname"] valueForKey:#"text"]];
}
[mwCell.companyName setTextColor:t.formfgColor];
[mwCell.companyName setShadowColor:t.formShadowColor];
float br_preVal=[[[prevDict valueForKey:#"bestbuyprice"] valueForKey:#"text"] floatValue];
float br_nxtVal=[[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"] floatValue];
float sr_preVal=[[[prevDict valueForKey:#"bestsellprice"] valueForKey:#"text"] floatValue];
float sr_nxtVal=[[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"] floatValue];
if (br_nxtVal>br_preVal) {
[mwCell.buyRate setBackgroundColor:t.socketHighbgColor];
mwCell.buyRate.textColor=t.socketHighfgColor;
}
if (br_nxtVal<br_preVal){
[mwCell.buyRate setBackgroundColor:t.socketLowbgColor];
mwCell.buyRate.textColor=t.socketLowfgColor;
}
if (sr_nxtVal>sr_preVal) {
[mwCell.sellRate setBackgroundColor:t.socketHighbgColor];
[mwCell.sellRate setTextColor:t.socketHighfgColor];
}
if (sr_nxtVal<sr_preVal) {
[mwCell.sellRate setBackgroundColor:t.socketLowbgColor];
[mwCell.sellRate setTextColor:t.socketLowfgColor];
}
NSLog(#"tag of cell at index %i is %i",indexPath.row,mwCell.tag);
mwCell.buyRate.textAlignment=NSTextAlignmentCenter;
mwCell.sellRate.textAlignment=NSTextAlignmentCenter;
mwCell.buyRate.text=[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"];
mwCell.sellRate.text=[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"];
[mwCell.buyRate setShadowOffset:CGSizeMake(0, 0)];
[mwCell.sellRate setShadowOffset:CGSizeMake(0, 0)];
if ([mwCell.buyRate.text floatValue]<0) {
[mwCell.buyRate setBackgroundColor:t.socketLowbgColor];
[mwCell.buyRate setTextColor:t.socketLowfgColor];
}
if ([mwCell.sellRate.text floatValue]<0) {
[mwCell.sellRate setBackgroundColor:t.socketLowbgColor];
[mwCell.sellRate setTextColor:t.socketLowfgColor];
}
return mwCell;
}
MWCell h file
#interface MWCell : UITableViewCell
#property(nonatomic,strong)IBOutlet UILabel *companyName,*buyRate,*sellRate;
#property(nonatomic,strong)NSString *prev_br,*pre_sr;
#end
MWCell m file
#import "MWCell.h"
#implementation MWCell
#synthesize companyName,buyRate,sellRate;
#synthesize pre_sr,prev_br;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
pre_sr=#"";
prev_br=#"";
// Initialization code
}
return self;
}
#end
It is working fine , but facing problem while scrolling.
If I scroll tableView its color automatically changes (even if no data coming from socket).I know every time we scroll tableView cell prepares and that causes custom cell's label color to change.
Is there any solution for this.
my screen shot is given below:----
Thanks!.
Apply an alternative to set previous color:--
take two NSMutableArray and init with white colors.
NSMutableArray *celllc,*cellrc;
prevScriptArray=[NSArray arrayWithArray:watchScriptArray];
[celllc removeAllObjects];
[cellrc removeAllObjects];
for (int i=0;i<[watchScriptArray count];i++) {
[cellrc addObject:[UIColor whiteColor]];
[celllc addObject:[UIColor whiteColor]];
}
Every time create cell by setting mwCell object to nil before checking it if(mwcell==nil)
and set color to cell from array of color as given below in cellforRowAtIndexPath method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"cellIdentifier"];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cellIdentifier"];
}
MWCell *mwCell=(MWCell*)[tableView dequeueReusableCellWithIdentifier:#"mwCellIdentifier"];
if (mwCell!=nil)mwCell=nil;
if (mwCell==nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle] loadNibNamed:#"MWCell" owner:self options:nil];
for (id temp in topLevelObjects) {
if ([temp isKindOfClass:[MWCell class]]) {
mwCell=(MWCell*)temp;
mwCell.buyRate.backgroundColor=[celllc objectAtIndex:indexPath.row];
mwCell.sellRate.backgroundColor=[cellrc objectAtIndex:indexPath.row];
mwCell.buyRate.textColor=([[celllc objectAtIndex:indexPath.row] isEqual:t.socketLowbgColor])?t.socketLowfgColor:t.socketHighfgColor;
mwCell.sellRate.textColor=([[cellrc objectAtIndex:indexPath.row] isEqual:t.socketLowbgColor])?t.socketLowfgColor:t.socketHighfgColor;
}
}
}
NSDictionary *tempDic=[watchScriptArray objectAtIndex:indexPath.row];
NSDictionary *prevDict=[prevScriptArray objectAtIndex:indexPath.row];
if ([[tempDic valueForKey:#"expirydate"] valueForKey:#"text"]) {
mwCell.companyName.text=[NSString stringWithFormat:#"%#-%#",[[tempDic valueForKey:#"symbolname"] valueForKey:#"text"],[[tempDic valueForKey:#"expirydate"] valueForKey:#"text"]];
}else{
mwCell.companyName.text=[NSString stringWithFormat:#"%#",[[tempDic valueForKey:#"symbolname"] valueForKey:#"text"]];
}
[mwCell.companyName setTextColor:t.formfgColor];
[mwCell.companyName setShadowColor:t.formShadowColor];
float br_preVal=[[[prevDict valueForKey:#"bestbuyprice"] valueForKey:#"text"] floatValue];
float br_nxtVal=[[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"] floatValue];
float sr_preVal=[[[prevDict valueForKey:#"bestsellprice"] valueForKey:#"text"] floatValue];
float sr_nxtVal=[[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"] floatValue];
if (br_nxtVal>br_preVal) {
[mwCell.buyRate setBackgroundColor:t.socketHighbgColor];
mwCell.buyRate.textColor=t.socketHighfgColor;
[celllc replaceObjectAtIndex:indexPath.row withObject:t.socketHighbgColor];
}
if (br_nxtVal<br_preVal){
[mwCell.buyRate setBackgroundColor:t.socketLowbgColor];
mwCell.buyRate.textColor=t.socketLowfgColor;
[celllc replaceObjectAtIndex:indexPath.row withObject:t.socketLowbgColor];
}
if (sr_nxtVal>sr_preVal) {
[mwCell.sellRate setBackgroundColor:t.socketHighbgColor];
[mwCell.sellRate setTextColor:t.socketHighfgColor];
[cellrc replaceObjectAtIndex:indexPath.row withObject:t.socketHighbgColor];
}
if (sr_nxtVal<sr_preVal) {
[mwCell.sellRate setBackgroundColor:t.socketLowbgColor];
[mwCell.sellRate setTextColor:t.socketLowfgColor];
[cellrc replaceObjectAtIndex:indexPath.row withObject:t.socketLowbgColor];
}
NSLog(#"tag of cell at index %i is %i",indexPath.row,mwCell.tag);
mwCell.buyRate.textAlignment=NSTextAlignmentCenter;
mwCell.sellRate.textAlignment=NSTextAlignmentCenter;
mwCell.buyRate.text=[[tempDic valueForKey:#"bestbuyprice"] valueForKey:#"text"];
mwCell.sellRate.text=[[tempDic valueForKey:#"bestsellprice"] valueForKey:#"text"];
[mwCell.buyRate setShadowOffset:CGSizeMake(0, 0)];
[mwCell.sellRate setShadowOffset:CGSizeMake(0, 0)];
if ([mwCell.buyRate.text floatValue]<0) {
[mwCell.buyRate setBackgroundColor:t.socketLowbgColor];
[mwCell.buyRate setTextColor:t.socketLowfgColor];
}
if ([mwCell.sellRate.text floatValue]<0) {
[mwCell.sellRate setBackgroundColor:t.socketLowbgColor];
[mwCell.sellRate setTextColor:t.socketLowfgColor];
}
return mwCell;
}
Better answer will be appreciated.If any?
Related
i am trying to achieve indexing on table for that i use following method indexing appears on right side but it is not working code is below
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSArray *toBeReturned = [NSArray arrayWithArray:
[#"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#"
componentsSeparatedByString:#"|"]];
return toBeReturned;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
int foundIndex = 0;
for (int i = 0; i< [mainArray count]; i++) {
// Here you return the name i.e. Honda,Mazda
// and match the title for first letter of name
// and move to that row corresponding to that indexpath as below
NSString *letterString = [[[mainArray valueForKey:#"name"] objectAtIndex:i] substringToIndex:1];
NSLog(#"letterString%#",letterString);
NSLog(#"title%#",title);
if ([[letterString uppercaseString ] compare:title] == NSOrderedDescending){
break;
foundIndex++; }
if(foundIndex > mainArray.count)
foundIndex = mainArray.count;
[table scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:foundIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
return 1;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 120;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//—set the text to display for the cell—
NSLog(#"%d",mainArray.count);
NSLog(#"%#",mainArray);
UIImageView *selectionView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 768, 120)];
UIImage *image = [UIImage imageNamed:#"default.png"];
UIImageView* blockView = [[UIImageView alloc] initWithImage:image];
blockView.layer.cornerRadius = 4;
blockView.layer.masksToBounds = YES;
blockView.layer.borderWidth = 2;
blockView.layer.borderColor = [UIColor blackColor].CGColor;
blockView.frame = CGRectMake(5, 5, 110, 110);
// title isKindOfClass:[NSNull class]])
//NSLog(#"%#",[[mainArray valueForKey:#"image"] objectAtIndex:[indexPath row]]);
id obj = [[mainArray valueForKey:#"image"] objectAtIndex:[indexPath row]];
if ([obj isKindOfClass:[NSString class]])
{
[selectionView addSubview:blockView];
}
else {
UIImage *contactImage = [[UIImage alloc]init];
contactImage = [[mainArray valueForKey:#"image"] objectAtIndex:[indexPath row]];
// NSLog(#" array%#",[[mainArray valueForKey:#"image"] objectAtIndex:[indexPath row]]);
NSLog(#" image%#",contactImage);
UIImageView *blockView = [[UIImageView alloc] initWithImage:contactImage];
blockView.frame = CGRectMake(5, 5, 110, 110);
blockView.layer.cornerRadius = 4;
blockView.layer.masksToBounds = YES;
blockView.layer.borderWidth = 2;
blockView.layer.borderColor = [UIColor blackColor].CGColor;
[selectionView addSubview:blockView];
}
NSLog(#" name :%#",[[mainArray valueForKey:#"name"] objectAtIndex:[indexPath row]]);
if ([[[mainArray valueForKey:#"name"] objectAtIndex:[indexPath row]] isEqualToString:#"(null)"]) {
UILabel *name = [[UILabel alloc]initWithFrame:CGRectMake(130, 10, 310, 55)];
name.text =#"Name Not Available";
[name setBackgroundColor:[UIColor clearColor]];
[ name setFont:[UIFont fontWithName:#"Arial-BoldMT" size:30]];
name.textColor = [UIColor whiteColor];
[selectionView addSubview:name];
}
else{
UILabel *name = [[UILabel alloc]initWithFrame:CGRectMake(130, 10, 310, 55)];
name.text =[[mainArray valueForKey:#"name"] objectAtIndex:[indexPath row]];
[name setBackgroundColor:[UIColor clearColor]];
[ name setFont:[UIFont fontWithName:#"Arial-BoldMT" size:30]];
name.textColor = [UIColor whiteColor];
[selectionView addSubview:name];
}
if ([[[mainArray valueForKey:#"phone"] objectAtIndex:[indexPath row]] isEqualToString:#"Add Number"]) {
UILabel *phone = [[UILabel alloc]initWithFrame:CGRectMake(130, 70, 300, 50)];
phone.text =#"Not Available";
[phone setBackgroundColor:[UIColor clearColor]];
[ phone setFont:[UIFont fontWithName:#"Arial-BoldMT" size:25]];
phone.textColor = [UIColor whiteColor];
[selectionView addSubview:phone];
}
else{
UILabel *phone = [[UILabel alloc]initWithFrame:CGRectMake(130, 70, 300, 50)];
phone.text =[[mainArray valueForKey:#"phone"] objectAtIndex:[indexPath row]];
[phone setBackgroundColor:[UIColor clearColor]];
[ phone setFont:[UIFont fontWithName:#"Arial-BoldMT" size:25]];
phone.textColor = [UIColor whiteColor];
[selectionView addSubview:phone];
}
if ([[[mainArray valueForKey:#"email"] objectAtIndex:[indexPath row]] isEqualToString:#"Add Email"]) {
UILabel *email = [[UILabel alloc]initWithFrame:CGRectMake(420, 40, 350, 50)];
email.text =#"Email Id Not Available";
[email setBackgroundColor:[UIColor clearColor]];
[ email setFont:[UIFont fontWithName:#"Arial-BoldMT" size:20]];
email.textColor = [UIColor whiteColor];
[selectionView addSubview:email];
}
else{
UILabel *email = [[UILabel alloc]initWithFrame:CGRectMake(420, 40, 350, 50)];
email.text =[[mainArray valueForKey:#"email"] objectAtIndex:[indexPath row]];
[email setBackgroundColor:[UIColor clearColor]];
[ email setFont:[UIFont fontWithName:#"Arial-BoldMT" size:20]];
email.textColor = [UIColor whiteColor];
[selectionView addSubview:email];
}
[[cell contentView] addSubview:selectionView];
return cell;
}
what problem i face is it reach top of the table when i click any index and not right index
To use the index your table should really be broken into sections. It looks like currently you are asking the framework to scroll to a specified row and then to scroll to the top of section 0 immediately afterwards.
It may work if you use performSelector to request the scroll after a short delay (it may look nasty). Or possibly if you return -1 from the method (documentation does not support this guess).
The answer really is to use sections in your table and let the framework work as designed.
when we have section 0 then we can do like this
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSArray *toBeReturned = [NSArray arrayWithArray:
[#"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z"
componentsSeparatedByString:#"|"]];
return toBeReturned;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
int foundIndex = 0;
for (int i = 0; i< [mainArray count]; i++) {
NSString *letterString = [[[mainArray valueForKey:#"name"] objectAtIndex:i] substringToIndex:1];
NSLog(#"letterString%#",letterString);
NSLog(#"title%#",title);
if ([letterString caseInsensitiveCompare:title] == NSOrderedSame)
{
break;
}
else{
foundIndex++;
NSLog(#"founded index %d",foundIndex);
}
}
NSLog(#"founded index %d",mainArray.count);
NSLog(#"founded index %d",foundIndex);
if(foundIndex >= mainArray.count){
foundIndex = mainArray.count-1;
}
NSLog(#"founded index %d",foundIndex);
[table scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:foundIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
return 1;
}
.h
#import <TapkuLibrary/TapkuLibrary.h>
#import <UIKit/UIKit.h>
#import <EventKit/EventKit.h>
#interface CalendarMonthViewController : TKCalendarMonthTableViewController{
NSMutableArray *events;
EKEventStore *eventStore;
NSDate *startDatee;
NSDate *lastDatee;
}
#property (strong,nonatomic) NSMutableArray *dataArray;
#property (strong,nonatomic) NSMutableDictionary *dataDictionary;
- (void) generateRandomDataForStartDate:(NSDate*)start endDate:(NSDate*)end;
#end
.m
#import "CalendarMonthViewController.h"
#import "AppDelegate.h"
#implementation CalendarMonthViewController
#pragma mark - View Lifecycle
- (void) viewDidLoad{
[super viewDidLoad];
[self.monthView selectDate:[NSDate month]];
}
-(void)viewWillAppear:(BOOL)animated{
[self updateTableOffset:YES];
NSLog(#"hi ha ");
}
-(void)fatchAllEvent{
eventStore = [[EKEventStore alloc] init];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
__block typeof (self) weakSelf = self; // replace __block with __weak if you are using ARC
dispatch_async(dispatch_get_main_queue(), ^{
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSLog(#" granted");
[weakSelf performSelectorOnMainThread:#selector(allCalendarEvent) withObject:nil waitUntilDone:YES];
}
else
{
NSLog(#"Not granted");
}
}];
});
}
else
{
[self allCalendarEvent];
}
}
-(void)allCalendarEvent{
NSDate *startDate = [NSDate distantPast];
NSDate *endDate = [NSDate distantFuture];
// use Dictionary for remove duplicates produced by events covered more one year segment
NSMutableDictionary *eventsDict = [NSMutableDictionary dictionaryWithCapacity:1024];
NSDate* currentStart = [NSDate dateWithTimeInterval:0 sinceDate:startDate];
int seconds_in_year = 60*60*24*365;
// enumerate events by one year segment because iOS do not support predicate longer than 4 year !
while ([currentStart compare:endDate] == NSOrderedAscending) {
NSDate* currentFinish = [NSDate dateWithTimeInterval:seconds_in_year sinceDate:currentStart];
if ([currentFinish compare:endDate] == NSOrderedDescending) {
currentFinish = [NSDate dateWithTimeInterval:0 sinceDate:endDate];
}
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:currentStart endDate:currentFinish calendars:nil];
[eventStore enumerateEventsMatchingPredicate:predicate
usingBlock:^(EKEvent *event, BOOL *stop) {
if (event) {
[eventsDict setObject:event forKey:event.eventIdentifier];
}
}];
currentStart = [NSDate dateWithTimeInterval:(seconds_in_year + 1) sinceDate:currentStart];
}
events = [[NSMutableArray alloc]init];
for (id key in eventsDict) {
id anObject = [eventsDict objectForKey:key];
[events addObject:anObject];
/* Do something with anObject. */
}
NSLog(#"all event %#",events);
CFRunLoopStop(CFRunLoopGetCurrent());
// NSLog(#"all event crash%#",events);
}
#pragma mark - MonthView Delegate & DataSource
- (NSArray*) calendarMonthView:(TKCalendarMonthView*)monthView marksFromDate:(NSDate*)startDate toDate:(NSDate*)lastDate{
if (!events) {
[self fatchAllEvent];
CFRunLoopRun();
}
NSLog(#"all event %#",events);
[self generateRandomDataForStartDate:startDate endDate:lastDate];
// NSLog(#"%#",self.dataDictionary);
NSLog(#"%#",self.dataArray);
NSLog(#"%#",self.dataDictionary);
NSLog(#"%#",[self.dataDictionary allKeys]);
return self.dataArray;
}
- (void) calendarMonthView:(TKCalendarMonthView*)monthView didSelectDate:(NSDate*)date{
// CHANGE THE DATE TO YOUR TIMEZONE
TKDateInformation info = [date dateInformationWithTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *myTimeZoneDay = [NSDate dateFromDateInformation:info timeZone:[NSTimeZone systemTimeZone]];
NSLog(#"Date Selected: %#",myTimeZoneDay);
[self.tableView reloadData];
}
- (void) calendarMonthView:(TKCalendarMonthView*)mv monthDidChange:(NSDate*)d animated:(BOOL)animated{
[super calendarMonthView:mv monthDidChange:d animated:animated];
[self.tableView reloadData];
}
#pragma mark - UITableView Delegate & DataSource
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad)
{
NSArray *views =[[NSBundle mainBundle] loadNibNamed:#"CalendarTableHeader" owner:nil options:nil];
UIView *headerView=[views objectAtIndex:0];
return headerView;
}
else
{
return nil;
}
}
- (CGFloat) tableView:(UITableView *) tableView heightForHeaderInSection:(NSInteger) section {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
return 25;
} else {
return 0;
}
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *ar = [self.dataDictionary objectForKey:[self.monthView dateSelected]];
if(ar == nil) return 0;
return [ar count];
}
- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSArray *ar = [self.dataDictionary objectForKey:[self.monthView dateSelected]];
cell.textLabel.text = [ar objectAtIndex:indexPath.row];
return cell;
}
- (BOOL)isDate:(NSDate *)date inRangeFirstDate:(NSDate *)firstDate lastDate:(NSDate *)lastDate {
return [date compare:firstDate] == NSOrderedDescending &&
[date compare:lastDate] == NSOrderedAscending;
}
- (void) generateRandomDataForStartDate:(NSDate*)start endDate:(NSDate*)end{
// this function sets up dataArray & dataDictionary
// dataArray: has boolean markers for each day to pass to the calendar view (via the delegate function)
// dataDictionary: has items that are associated with date keys (for tableview)
NSMutableArray *arrayOfDates = [[NSMutableArray alloc ]init];
NSMutableArray *arrayOfNames = [[NSMutableArray alloc ]init];
// NSLog(#"Delegate Range: %# %# %d",start,end,[start daysBetweenDate:end]);
NSDateFormatter *newformater=[[[NSDateFormatter alloc]init]autorelease];
[newformater setDateFormat:#"yyyy-MM-dd HH:mm:ss "];
NSDate *startD = [newformater dateFromString:[newformater stringFromDate:start]];
NSDate *endD = [newformater dateFromString:[newformater stringFromDate:end]];
NSLog(#"%#",events);
BOOL isAttempt = NO;
for (int i =0; i<arrayOfDates.count; i++) {
if ([start isEqualToDate:[arrayOfDates objectAtIndex:i]]) {
[self.dataDictionary setObject:[NSArray arrayWithObjects:[arrayOfNames objectAtIndex:i],nil] forKey:start];
[self.dataArray addObject:[NSNumber numberWithBool:YES]];
isAttempt = YES;
}
else{
isAttempt = NO;
}
}
if (!isAttempt) {
[self.dataArray addObject:[NSNumber numberWithBool:NO]];
}
for (int i = 0; i<events.count; i++) {
NSDate *eventDate = [[events valueForKey:#"startDate"] objectAtIndex:i];
NSString *eventName = [[events valueForKey:#"title"]objectAtIndex:i];
NSLog(#"startreal%#",start);
NSLog(#"endreal%#",end);
NSLog(#"eventName:::%#",eventName);
NSLog(#"start%#",startD);
NSLog(#"end%#",endD);
NSLog(#"eventDate%#",eventDate);
if([self isDate:eventDate inRangeFirstDate:startD lastDate:endD]){
[arrayOfDates addObject:eventDate];
[arrayOfNames addObject:eventName];
}else{
}
}
NSLog(#"eventdate = %#",arrayOfDates);
NSLog(#"eventName = %#",arrayOfNames);
// the dates that we have will go thorought for loop and we wil check if its between start and end date then we will add that object to datadictionary or wont
[self.dataArray removeAllObjects];
[self.dataDictionary removeAllObjects];
self.dataArray = [NSMutableArray array];
self.dataDictionary = [NSMutableDictionary dictionary];
NSDate *d = start;
while(YES){
BOOL isAttempt = NO;
for (int i =0; i<arrayOfDates.count; i++) {
if ([d isEqualToDate:[arrayOfDates objectAtIndex:i]]) {
[self.dataDictionary setObject:[NSArray arrayWithObjects:[arrayOfNames objectAtIndex:i],nil] forKey:d];
[self.dataArray addObject:[NSNumber numberWithBool:YES]];
isAttempt = YES;
}
else{
isAttempt = NO;
}
}
if (!isAttempt) {
[self.dataArray addObject:[NSNumber numberWithBool:NO]];
}
TKDateInformation info = [d dateInformationWithTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
info.day++;
d = [NSDate dateFromDateInformation:info timeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
if([d compare:end]==NSOrderedDescending) break;
}
}
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self updateTableOffset:YES];
}
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end
How to remove all the items from indexPathSelectdItems. Below is my code I am using to save values to array from indexPathSelectedITems, but need to clear the array when section changes and array should save value as a fresh. But indexPathForSelectedItems add previousSelectedValues also.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *seatV;
int cs;
NSString *secVal = [arrSeatSel objectAtIndex:indexPath.section];
NSArray *arrSplit = [secVal componentsSeparatedByString:#":"];
seatV = [arrSplit objectAtIndex:1];
cs = [seatV integerValue];
int v;
NSString *cnt = [NSString stringWithFormat:#"%#",[arrTot objectAtIndex:indexPath.section]];
v = [cnt intValue];
NSString *sect = [NSString stringWithFormat:#"%d", indexPath.section];
if(indexPath.item < v)
{
if([sectionInfo count] < cs)
{
itemPaths = [self.collectionView indexPathsForSelectedItems];
//NSMutableArray *array = [NSMutableArray array];
//array = [self.collectionView indexPathsForSelectedItems];
//sectionInfo = [self.collectionView indexPathsForSelectedItems];
sectionInfo = [NSMutableArray arrayWithArray: [self.collectionView indexPathsForSelectedItems]];
//[sectionInfo addObject:[[self.collectionView indexPathsForSelectedItems] lastObject]];
[selectedItemsInfo setObject:sectionInfo forKey:sect];
cell=[self.collectionView cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"yellow_seat.png"]];
//sectionInfo1 = sectionInfo;
}
else
{
[self.collectionView deselectItemAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row inSection:indexPath.section] animated:YES];
[sectionInfo1 addObject:[selectedItemsInfo objectForKey:sect]];
[selectedItemsInfo setObject:sectionInfo1 forKey:sect];
[sectionInfo removeAllObjects];
}
}
else
{
[self.collectionView deselectItemAtIndexPath:[NSIndexPath indexPathForItem:indexPath.row inSection:indexPath.section] animated:YES];
}
NSLog(#"section array:%#", sectionInfo);
NSLog(#"section array1:%#", sectionInfo1);
NSLog(#"selected seats dict:%#", selectedItemsInfo);
}
So, how to clear previous values indexPathSelectedItems so that it can hold new selected values only?
Try using this code as per your requirement.
[self deleteItemsFromDataSourceAtIndexPaths:selectedItemsIndexPaths];
OR
[self.collectionView deleteItemsAtIndexPaths:selectedItemsIndexPaths];
I'm trying to do search but its not working for me perfectly .What i need that when I enter B then i should get all the words that starts with B . I'm still wondering where i'm doing wrong. i'm very new to ios.
here is my code :-
ContactViewController.h
#import <UIKit/UIKit.h>
#interface ContactViewController :
UIViewController<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>
{
UISearchBar* searchBar;
IBOutlet UITableView* contactTableView;
NSMutableArray *listOfItems;
NSMutableArray *copyListOfItems;
NSArray *content;
NSArray *indices;
NSArray* contacts;
BOOL searching;
BOOL letUserSelectRow;
}
-(void)btn_AddContact;
#end
ContactViewController.m
#import "ContactViewController.h"
#import "AddContactsViewController.h"
#import "CustomCell.h"
#import "DataGenerator.h"
#interface ContactViewController ()
#end
#implementation ContactViewController
- (void)viewDidLoad
{
[super viewDidLoad];
const NSInteger searchBarHeight = 45;
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320,
searchBarHeight)];
[self.view addSubview:searchBar];
searchBar.delegate = self;
[self.view addSubview:searchBar];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:#"Refresh"
style:UIBarButtonItemStyleBordered target:self action:#selector(onAddContact)];
self.navigationItem.rightBarButtonItem = addButton;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:20.0];
label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textAlignment = UITextAlignmentCenter;
label.textColor = [UIColor whiteColor]; // change this color
self.navigationItem.titleView = label;
label.text = NSLocalizedString(#"All Contacts", #"");
[label sizeToFit];
content = [DataGenerator wordsFromLetters];
indices = [[content valueForKey:#"headerTitle"] retain];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [content count];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section {
return [[[content objectAtIndex:section] objectForKey:#"rowValues"] count] ;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
if(searching) {
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[NSString stringWithFormat:#"%# %# %#",
#"pauline.abraham#gmail.com", #" |",#"123456777"] ;
}else {
cell.textLabel.text = [[[content objectAtIndex:indexPath.section]
objectForKey:#"rowValues"]
objectAtIndex:indexPath.row];
//cell.detailTextLabel.numberOfLines=2;
//cell.detailTextLabel.lineBreakMode=NSLineBreakByWordWrapping;
cell.detailTextLabel.text=[NSString stringWithFormat:#"%# %# %#",
#"pauline.abraham#gmail.com", #" |",#"123456777"] ;
}
return cell;
}
- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:
(NSInteger)section {
return [[content objectAtIndex:section] objectForKey:#"headerTitle"];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [content valueForKey:#"headerTitle"];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:
(NSString *)title atIndex:(NSInteger)index {
return [indices indexOfObject:title];
}
-(void)onAddContact
{
// AddContactsViewController* add = [[AddContactsViewController alloc]
initWithNibName:#"AddContactsViewController" bundle:nil];
// [self.navigationController pushViewController:add animated:YES];
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
if(searching)
return;
searching = YES;
letUserSelectRow = NO;
[contactTableView setScrollEnabled:NO];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self
action:#selector(btn_DoneSearch)];
}
-(void)btn_DoneSearch
{
searchBar.text = #"";
[searchBar resignFirstResponder];
searching = NO;
letUserSelectRow = YES;
[contactTableView setScrollEnabled:YES];
self.navigationItem.rightBarButtonItem = nil;
[contactTableView reloadData];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
//Remove all objects first.
[copyListOfItems removeAllObjects];
if([searchText length] > 0){
searching = YES;
letUserSelectRow = YES;
[contactTableView setScrollEnabled:YES];
[self searchTableView];
}else {
searching = NO;
letUserSelectRow = NO;
[contactTableView setScrollEnabled:NO];
}
[contactTableView reloadData];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self searchTableView];
}
-(void)searchTableView
{
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in content)
{
NSArray *array = [dictionary objectForKey:#"rowValues"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText
options:NSCaseInsensitiveSearch];
if (titleResultsRange.length>0)
{
[copyListOfItems addObject:sTemp];
NSLog(#"lenght : %d",titleResultsRange.length );
}
}
searchArray = nil;
}
#end
see this below code also you not add the rows related searched data put this condition in below 3 delegate method of UITableView also
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return [content count];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return [copyListOfItems count];
else
return [[[content objectAtIndex:section] objectForKey:#"rowValues"] count] ;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(searching)
return #"";
else
return [[content objectAtIndex:section] objectForKey:#"headerTitle"];
}
I need to sort by value instead of Key, I think....
Heres where I populate my arrarys
const char *sql = "select cid, category from Categories ORDER BY category DESC";
sqlite3_stmt *statementTMP;
int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {
while(sqlite3_step(statementTMP) == SQLITE_ROW)
{
int cid = sqlite3_column_int(statementTMP, 0);
NSString *category = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
NSArray *arr=[[NSArray alloc]initWithObjects:category,nil];
[arrayTmp setObject:arr forKey:[NSString stringWithFormat:#"%i",cid]];
[self.cidList addObject:[NSString stringWithFormat:#"%i",cid]];
[category release];
[arr release];
}
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
self.allCategories = arrayTmp;
[arrayTmp release];
Heres the method where the arrays are re-sorted.
- (void)resetSearch {
NSMutableDictionary *allCategoriesCopy = [self.allCategories mutableDeepCopy];
self.Categories = allCategoriesCopy;
[allCategoriesCopy release];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
[keyArray addObject:UITableViewIndexSearch];
[keyArray addObjectsFromArray:[[self.allCategories allKeys]
sortedArrayUsingSelector:#selector(compare:)]];
self.keys = keyArray;
[keyArray release];
}
This is a problem i've had for some time, last time I looked at this I could find an altervative to sortedArrayUsingSelector compare?
EDIT
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [Categories objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SectionsTableIdentifier ];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier: SectionsTableIdentifier ] autorelease];
}
cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [Categories objectForKey:key];
NSLog(#"the selected cid is = %i",[key intValue]);
selectButton.enabled = YES;
}
Anyone?
Your obviously attempting to construct an array for use in the -[UITableviewDatasource sectionIndexTitlesForTableView:]. As such, you need an array that looks like this (pseudo-code):
[UITableViewIndexSearch, 0_sectionTitle, 1_sectionTitle, 2_sectionTitle, ...]
I think your immediate problem is that you try to add the UITableViewIndexSearch string constant to the array before you sort which makes it impossible for it end up as the first element unless all your other elements sort below U.
The fix is simple, just add the constant after the sort. You can clean the code up while you're at it:
NSMutableArray *secIdx=[NSMutableArray arrayWithCapacity:[[self.allCategories allKeys] count]];
[secIdx addObjectsFromArray:[self.allCategories allKeys]];
[secIdx sortUsingSelector:#selector(compare:)];
[secIdx insertObject:UITableViewIndexSearch atIndex:0];
self.keys=secIdx;
Note that secIdx is autoreleased so you don't have to release it.
Aside from this problem, your code has a lot of unnecessary/dangerous elements that will make your app fragile and hard to maintain.
You are using a lot of init for objects that you could use autoreleased convenience methods for. The 'init`s poise the risk of memory leaks but give you no advantage.
You need to wrap scalar values in objects so they can be easily managed in collections.
You are using an unnecessary array.
You can rewrite the first block like so:
const char *sql = "select cid, category from Categories ORDER BY category DESC";
sqlite3_stmt *statementTMP;
int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {
NSNumber *cidNum; //... move variable declerations outside of loop
NSString *category; //.. so they are not continously recreated
[self.allCategories removeAllObjects]; //... clears the mutable dictionary instead of replacing it
while(sqlite3_step(statementTMP) == SQLITE_ROW){
cidNum=[NSNumber numberWithInt:(sqlite3_column_int(statementTMP, 0))];
category=[NSString stringWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
//... adding the autoreleased category and cidNum to array/dictionary automatically retains them
[self.allCategories addObject:category forKey:cidNum];
[self.cidList addObject:cidNum];
//[category release]; ... no longer needed
//[arr release]; ... no longer needed
}
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
//self.allCategories = arrayTmp; ... no longer needed
//[arrayTmp release]; ... no longer needed
Use -sortedArrayUsingComparator: (or -sortedArrayUsingFunction:context: if you can't use blocks). Example:
NSDictionary *categories = [self allCategories];
NSArray *keysSortedByValue = [[categories allKeys] sortedArrayUsingComparator:
^(id left, id right) {
id lval = [categories objectForKey:left];
id rval = [categories objectForKey:right];
return [lval compare:rval];
}];
You could make a small model class Category and implement compare inside of it, then sort an array of those objects using that compare:.
Here's some info - How to sort an NSMutableArray with custom objects in it?
Perhaps you're looking for NSSortDescriptor (and the corresponding sort method, -[NSArray sortedArrayUsingDescriptors]) and friends?
If I understood correctly then what you wish to do to get categories from database & display it on a tableView with alphabetical sorting, index on right & search bar on top. Ideally, you would like to display the Contacts application kind of a view. If that's correct, use below code for fetching items from DB & rebuilding (or resetting) it -
const char *sql = "select cid, category from Categories ORDER BY category DESC";
sqlite3_stmt *statementTMP;
NSMutableArray *arrayTmp = [[NSMutableArray alloc] init];
int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {
while(sqlite3_step(statementTMP) == SQLITE_ROW) {
int cid = sqlite3_column_int(statementTMP, 0);
NSString *category = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:category forKey:#"Category"];
[dict setObject:[NSNumber numberWithInt:cid] forKey:#"CID"];
[arrayTmp addObject:dict];
[dict release];
[category release];
}
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
self.allCategories = arrayTmp;
[arrayTmp release];
And then rebuild the items using this function -
- (void)rebuildItems {
NSMutableDictionary *map = [NSMutableDictionary dictionary];
for (int i = 0; i < allCategories.count; i++) {
NSString *name = [[allCategories objectAtIndex:i] objectForKey:#"Category"];
NSString *letter = [name substringToIndex:1];
letter = [letter uppercaseString];
if (isdigit([letter characterAtIndex:0]))
letter = #"#";
NSMutableArray *section = [map objectForKey:letter];
if (!section) {
section = [NSMutableArray array];
[map setObject:section forKey:letter];
}
[section addObject:[allCategories objectAtIndex:i]];
}
[_items release];
_items = [[NSMutableArray alloc] init];
[_sections release];
_sections = [[NSMutableArray alloc] init];
NSArray* letters = [map.allKeys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
for (NSString* letter in letters) {
NSArray* items = [map objectForKey:letter];
[_sections addObject:letter];
[_items addObject:items];
}
}
Now, displaying items in tableView, use below methods -
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
if (_sections.count)
return _sections.count;
else
return 1;
}
- (NSInteger)tableView:(UITableView*)tableView sectionForSectionIndexTitle:(NSString *)title
atIndex:(NSInteger)index {
if (tableView.tableHeaderView) {
if (index == 0) {
[tableView scrollRectToVisible:tableView.tableHeaderView.bounds animated:NO];
return -1;
}
}
NSString* letter = [title substringToIndex:1];
NSInteger sectionCount = [tableView numberOfSections];
for (NSInteger i = 0; i < sectionCount; i++) {
NSString* section = [tableView.dataSource tableView:tableView titleForHeaderInSection:i];
if ([section hasPrefix:letter]) {
return i;
}
}
if (index >= sectionCount) {
return sectionCount-1;
} else {
return index;
}
}
- (NSArray*)lettersForSectionsWithSearch:(BOOL)withSearch withCount:(BOOL)withCount {
if (isSearching)
return nil;
if (_sections.count) {
NSMutableArray* titles = [NSMutableArray array];
if (withSearch) {
[titles addObject:UITableViewIndexSearch];
}
for (NSString* label in _sections) {
if (label.length) {
NSString* letter = [label substringToIndex:1];
[titles addObject:letter];
}
}
if (withCount) {
[titles addObject:#"#"];
}
return titles;
} else {
return nil;
}
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [self lettersForSectionsWithSearch:YES withCount:NO];
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
if (_sections.count) {
NSArray* items = [_items objectAtIndex:section];
return items.count;
} else {
return _items.count;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (_sections.count)
return [_sections objectAtIndex:section];
return nil;
}
- (id)tableView:(UITableView *)tableView objectForRowAtIndexPath:(NSIndexPath *)indexPath {
if (_sections.count) {
NSArray *section = [_items objectAtIndex:indexPath.section];
return [section objectAtIndex:indexPath.row];
} else {
return [_items objectAtIndex:indexPath.row];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create your UITableViewCell.
// Configure the cell.
NSDictionary *dict = [self tableView:tableView objectForRowAtIndexPath:indexPath];
cell.textLabel.text = [dict objectForKey:#"Category"];
cell.detailTextLabel.text = [NSString stringWithFormat:%d, [[dict objectForKey:#"CID"] intValue]];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (isSearching)
return nil;
NSString *title = #"";
if (_sections.count) {
title = [[_sections objectAtIndex:section] substringToIndex:1];
} else {
return nil;
}
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
view.backgroundColor = [UIColor colorWithRed:(58/255.0) green:(27/255.0) blue:(6/255.0) alpha:1.0];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 1, 50, 18)];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.text = title;
[view addSubview:label];
[label release];
return [view autorelease];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dict = [self tableView:tableView objectForRowAtIndexPath:indexPath];
NSLog(#"selected row id:%d, name:%#", [dict objectForKey:#"Category"], [[dict objectForKey:#"CID"] intValue]);
}
The rest part is implementing the UISearchBarDelegate and implementing searching of tableView which can be done using below code:
- (void)searchBar:(UISearchBar *)searchbar textDidChange:(NSString *)searchText {
[_sections removeAllObjects];
[_items removeAllObjects];
if([searchText isEqualToString:#""] || searchText == nil) {
[self rebuildItems];
return;
}
NSInteger counter = 0;
for(NSDictionary *dict in allCategories) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSRange r = [[dict objectForKey:#"Category"] rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(r.location != NSNotFound) {
if(r.location == 0) {
[_items addObject:dict];
}
}
counter++;
[pool release];
}
[contactList reloadData];
}
Hope this is what you're looking for.
On your sorting function u should try this:
NSArray *cntxt; //im not sure this is the correct type that ur using on keyArray
[keyArray addObjectsFromArray:[self.allCategories allKeys]];
[keyArray sortUsingFunction:compareFunction context:cntxt];
And the compare function you modify to your needs
NSInteger compareFunction(id x, id y, void *context) {
//NSArray *ctxt = context;
NSArray *c1 = x;
NSArray *c2 = y;
if ([c1 value] < [c2 value])
return NSOrderedDescending;
else if ([c1 value] > [c2 value])
return NSOrderedAscending;
else
return NSOrderedSame;
}
Edit: After reading your comments and after relooking at your code, it seems like that your keyArray as objects of the type NSString, so you should change:
NSInteger compareFunction(id x, id y, void *context) {
//NSString *ctxt = context;
NSString *c1 = x;
NSString *c2 = y;
NSComparisonResult result;
result = [c1 compare:c2];
if (result<0)
return NSOrderedAscending;
else if (result>0)
return NSOrderedDescending;
else
return NSOrderedSame;
}
I have a question about adding XML to the searchbar in a tableview. I can get all the external XML file to load in the tableview, but when I hit the searchbar up top, and hit a letter, it crashes.
I think it's something really simple that I'm doing wrong. In my RootViewController, there's a function called searchTableView. I feel like that's where it's not picking up the search items. I think it's somewhere around the objectForKey:#"title". When I debug, I get this error message also: "NSCFArray objectForKey unrecognized selector". Here's my searchTableView function:
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSArray *array = [dictionary objectForKey:#"title"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
Ok figured it out. For some reason this was really hard to find documentation how to do this.
Here's my RootViewController.m below.
My pList is configured as:
Root (Array)
Item0 (Dictionary)
Name (String)
Item1 (Dictionary)
Name (String)..
Here's my code, hopefully this helps anyone else looking for help on this:
#implementation RootViewController
#synthesize listOfItems, copyListOfItems;
- (void)viewDidLoad {
[super viewDidLoad];
//Initialize the array.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"plistArray" ofType:#"plist"];
NSMutableArray* tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
self.listOfItems = tmpArray;
[tmpArray release];
//Initialize the copy array.
copyListOfItems = [[NSMutableArray alloc] init];
//Set the title
self.navigationItem.title = #"Search";
//Add the search bar
self.tableView.tableHeaderView = searchBar;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searching = NO;
letUserSelectRow = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return [copyListOfItems count];
else {
//Number of rows it should expect should be based on the section
return [listOfItems count];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the selected country
NSString *selectedCountry = nil;
if(searching)
selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];
else {
// Navigation logic may go here. Create and push another view controller.
}
NSDictionary *dictionary = [self.listOfItems objectAtIndex:indexPath.row];
FoodDetail *dvController = [[FoodDetail alloc] initWithNibName:#"FoodDetail" bundle:nil andDictionary: dictionary];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
if(searching)
cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
else {
cell.textLabel.text = [[self.listOfItems objectAtIndex:indexPath.row]
objectForKey:#"Name"];
}
return cell;
}
- (NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(letUserSelectRow)
return indexPath;
else
return nil;
}
#pragma mark -
#pragma mark Search Bar
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from the detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:#"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = YES;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:#selector(doneSearching_Clicked:)] autorelease];
}
- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
//Remove all objects first.
[copyListOfItems removeAllObjects];
if([searchText length] > 0) {
[ovController.view removeFromSuperview];
searching = YES;
letUserSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self searchTableView];
}
else {
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = NO;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
}
[self.tableView reloadData];
}
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {
[self searchTableView];
}
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSString *text1 = [dictionary objectForKey:#"Name"];
[searchArray addObject:text1];
}
NSLog(#"%s: searchArray=%#", __func__, searchArray);
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
- (void) doneSearching_Clicked:(id)sender {
searchBar.text = #"";
[searchBar resignFirstResponder];
letUserSelectRow = YES;
searching = NO;
self.navigationItem.rightBarButtonItem = nil;
self.tableView.scrollEnabled = YES;
[ovController.view removeFromSuperview];
[ovController release];
ovController = nil;
[self.tableView reloadData];
}
- (void)dealloc {
[ovController release];
[copyListOfItems release];
[searchBar release];
[listOfItems release];
[super dealloc];
}
#end