How to convert iphone lazytableimages from .xib file to using storyboard? or any sample code using storyboard which are similiar to lazytableimages. The source code from https://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html
It doesn't matter where the controller's view comes from, be it xib, code or storyboard. The code of the controller does not change in that example's case, just make sure to put scene on storyboard, set it's view controller class and connect all the outlets.
#import "MasterListViewController.h"
#import "AppRecord.h"
#import "RootViewController.h"
#import "ParseOperation.h"
#define kCustomRowHeight 60.0
#define kCustomRowCount 7
static NSString *const TopPaidAppsFeed =
#"http://phobos.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/toppaidapplications/limit=75/xml";
#interface MasterListViewController ()
- (void)startIconDownload:(AppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath;
#end
#implementation MasterListViewController
#synthesize entries;
#synthesize imageDownloadsInProgress;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
self.tableView.rowHeight = kCustomRowHeight;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
NSArray *allDownloads = [self.imageDownloadsInProgress allValues];
[allDownloads makeObjectsPerformSelector:#selector(cancelDownload)];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = [entries count];
if (count == 0)
{
return kCustomRowCount;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// customize the appearance of table view cells
//
static NSString *CellIdentifier = #"LazyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
// add a placeholder cell while waiting on table data
int nodeCount = [self.entries count];
//NSLog(#"RootViewController - nodeCount is %d",nodeCount);
if (nodeCount == 0 && indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.detailTextLabel.text = #"Loading…";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Leave cells empty if there's no data yet
if (nodeCount > 0)
{
// Set up the cell...
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
cell.textLabel.text = appRecord.appName;
cell.detailTextLabel.text = appRecord.artist;
// Only load cached images; defer new downloads until scrolling ends
if (!appRecord.appIcon)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
// if a download is deferred or in progress, return a placeholder image
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
cell.imageView.image = appRecord.appIcon;
}
}
return cell;
}
- (void)startIconDownload:(AppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
IconDownloader *iconDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader == nil)
{
iconDownloader = [[IconDownloader alloc] init];
iconDownloader.appRecord = appRecord;
iconDownloader.indexPathInTableView = indexPath;
iconDownloader.delegate = self;
[imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
[iconDownloader startDownload];
}
}
- (void)loadImagesForOnscreenRows
{
if ([self.entries count] > 0)
{
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!appRecord.appIcon) // avoid the app icon download if the app already has an icon
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
// called by our ImageDownloader when an icon is ready to be displayed
- (void)appImageDidLoad:(NSIndexPath *)indexPath
{
IconDownloader *iconDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader != nil)
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:iconDownloader.indexPathInTableView];
// Display the newly loaded image
cell.imageView.image = iconDownloader.appRecord.appIcon;
}
// Remove the IconDownloader from the in progress list.
// This will result in it being deallocated.
[imageDownloadsInProgress removeObjectForKey:indexPath];
}
// Load images for all onscreen rows when scrolling is finished
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
}
#end
Related
i have a table view with section and i would like to start the table view with all section grouped like this:
Section1
Section2
Section3
When i tap on a section title, it expand the rows
Section1
Row1
Row2
Row3
Section2
Section3
i requested to all please see the answer if you dont like,just comment
this is for beginners....
this code also refered from net only and i changed few things
this link
creat class file...
ViewController.h file should be
#import <UIKit/UIKit.h>
#import "oneViewController.h"
#import "secondViewController.h"
#import "thirdViewController.h"
#interface ViewController : UIViewController
{
oneViewController *one;
secondViewController *second;
thirdViewController *third;
}
#end
ViewController.m file should be
#import "ViewController.h"
#import "Cell1.h"
#import "Cell2.h"
#interface ViewController()<UITableViewDataSource,UITableViewDelegate>
{
NSMutableArray *dataList;
}
#property (assign)BOOL isOpen;
#property (nonatomic,retain)NSIndexPath *selectIndex;
#property (nonatomic,retain)IBOutlet UITableView *expansionTableView;
#end
#implementation ViewController
#synthesize isOpen,selectIndex;
- (void)dealloc
{
[dataList release];
dataList= nil;
self.expansionTableView = nil;
self.isOpen = NO;
self.selectIndex = nil;
[super dealloc];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nil];
if (self) {
one=[[oneViewController alloc]init ];
second=[[secondViewController alloc]init];
third=[[thirdViewController alloc]init];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"array" ofType:#"plist"];
dataList = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(#"%lu",(unsigned long)dataList.count);
self.expansionTableView.sectionFooterHeight = 0;
self.expansionTableView.sectionHeaderHeight = 0;
self.isOpen = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [dataList count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.isOpen) {
if (self.selectIndex.section == section) {
return [[[dataList objectAtIndex:section] objectForKey:#"list"] count]+1;
}
}
return 1;
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",[[dataList objectAtIndex:indexPath.section]objectForKey:#"list"] );
if (self.isOpen&&indexPath.section == indexPath.section&&indexPath.row!=0) {
static NSString *CellIdentifier = #"Cell2";
Cell2 *cell = (Cell2*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
if ([[dataList objectAtIndex:indexPath.section]objectForKey:#"list"])
{
NSArray *list = [[dataList objectAtIndex:indexPath.section] objectForKey:#"list"];
cell.titleLabel.text = [list objectAtIndex:indexPath.row-1];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
return cell;
}else
{
static NSString *CellIdentifier = #"Cell1";
Cell1 *cell = (Cell1*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
NSString *name = [[dataList objectAtIndex:indexPath.section] objectForKey:#"name"];
cell.titleLabel.text = name;
//[cell changeArrowWithUp:([indexPath isEqual:indexPath]?YES:NO)];
if ([indexPath isEqual:indexPath])
{
[cell changeArrowWithUp:YES];
}
else
{
[cell changeArrowWithUp:NO];
}
return cell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
if ([indexPath isEqual:self.selectIndex]) {
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:self.selectIndex];
[cell changeArrowWithUp:YES];
self.isOpen = NO;
[self didSelectCellRowFirstDo:NO nextDo:NO];
self.selectIndex = nil;
}else
{
if (!self.selectIndex) {
self.selectIndex = indexPath;
[self didSelectCellRowFirstDo:YES nextDo:NO];
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:self.selectIndex];
[cell changeArrowWithUp:NO];
}else
{
NSIndexPath *tempIndex=indexPath;
if (tempIndex)
{
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:tempIndex];
[cell changeArrowWithUp:NO];
}
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:self.selectIndex];
[cell changeArrowWithUp:YES];
[self didSelectCellRowFirstDo:NO nextDo:YES];
}
}
}else
{
NSDictionary *dic = [dataList objectAtIndex:indexPath.section];
NSArray *list = [dic objectForKey:#"list"];
NSString *item = [list objectAtIndex:indexPath.row-1];
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"sample tree" message:item delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
// NSArray* temp=[NSArray arrayWithObjects:one,second,third,nil];
// [self viewPresent:[temp objectAtIndex:indexPath.row-1] sectionAt:item];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
//method for pushing view controller
-(void)viewPresent:(UIViewController *)viewName sectionAt:(NSString *)sectionValue
{
[[self navigationController]pushViewController:viewName animated:YES];
}
- (void)didSelectCellRowFirstDo:(BOOL)firstDoInsert nextDo:(BOOL)nextDoInsert
{
self.isOpen = firstDoInsert;
[self.expansionTableView beginUpdates];
int section = self.selectIndex.section;
int contentCount = [[[dataList objectAtIndex:section] objectForKey:#"list"] count];
NSMutableArray* rowToInsert = [[NSMutableArray alloc] init];
for (NSUInteger i = 1; i < contentCount + 1; i++) {
NSIndexPath* indexPathToInsert = [NSIndexPath indexPathForRow:i inSection:section];
[rowToInsert addObject:indexPathToInsert];
}
if (firstDoInsert)
{ [self.expansionTableView insertRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
else
{
[self.expansionTableView deleteRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
[rowToInsert release];
[self.expansionTableView endUpdates];
if (nextDoInsert) {
self.isOpen = YES;
self.selectIndex = [self.expansionTableView indexPathForSelectedRow];
[self didSelectCellRowFirstDo:YES nextDo:NO];
}
// if (self.isOpen) [self.expansionTableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
#end
then create two cell with subclass of UITableViewCell
the first cell should be
.h file
#import <UIKit/UIKit.h>
#interface Cell1 : UITableViewCell
#property (nonatomic,retain)IBOutlet UILabel *titleLabel;
#property (nonatomic,retain)IBOutlet UIImageView *arrowImageView;
- (void)indication:(BOOL)up;
#end
.m file
#import "Cell1.h"
#implementation Cell1
#synthesize titleLabel,arrowImageView;
- (void)dealloc
{
self.titleLabel = nil;
self.arrowImageView = nil;
[super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)indication:(BOOL)up
{
if (up) {
self.arrowImageView.image = [UIImage imageNamed:#"UpAccessory.png"];
}else
{
self.arrowImageView.image = [UIImage imageNamed:#"DownAccessory.png"];
}
}
the second cell should be
.h file
#import <UIKit/UIKit.h>
#interface Cell2 : UITableViewCell
#property (nonatomic,retain)IBOutlet UILabel *titleLabel;
#end
.m file
#import "Cell2.h"
#implementation Cell2
#synthesize titleLabel;
- (void)dealloc
{
self.titleLabel = nil;
[super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
for learning purpose my values are like below
(
{
list = (
1,
2,
3
);
name = Numbers;
},
{
list = (
a,
b,
c
);
name = Alaphabets;
},
{
list = (
India,
China,
Australia
);
name = Countries;
}
)
Im trying to figure out why my program runs well on simulator but not on Phone.
when i scroll my Tables it gets laggy.
ive tried everything , even removed my Images loading but still scroll lag happen.
Im using apple lazy loading source code :
this is my code :
#define kCustomRowCount 7
#interface SubCategoryViewController () <UIScrollViewDelegate>
#property (nonatomic, strong) NSMutableDictionary *imageDownloadsInProgress;
#property (nonatomic, strong) NSMutableDictionary *imageRestitleDownloadsInProgress;
#property (nonatomic, assign) int intindex;
#end
#implementation SubCategoryViewController
#pragma mark
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = self.catname;
self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
self.imageRestitleDownloadsInProgress = [NSMutableDictionary dictionary];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
NSArray *allDownloads = [self.imageDownloadsInProgress allValues];
[allDownloads makeObjectsPerformSelector:#selector(cancelDownload)];
NSArray *allDownloads2 = [self.imageRestitleDownloadsInProgress allValues];
[allDownloads2 makeObjectsPerformSelector:#selector(cancelDownload)];
[self.imageDownloadsInProgress removeAllObjects];
[self.imageRestitleDownloadsInProgress removeAllObjects];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger count = [self.entries count];
// if there's no data yet, return enough rows to fill the screen
if (count == 0)
{
return kCustomRowCount;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell2";
NSUInteger nodeCount = [self.entries count];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *newsbody = (UILabel *)[cell.contentView viewWithTag:6];
UIImageView *uimg = (UIImageView *)[cell.contentView viewWithTag:20];
UIImageView *uimgresttile = (UIImageView *)[cell.contentView viewWithTag:23];
if (nodeCount == 0 && indexPath.row == 0)
{
if (cell == nil) {
uimg.hidden = true;
uimgresttile.hidden = true;
newsbody.hidden = true;
}
else
{
uimg.hidden = true;
uimgresttile.hidden = true;
newsbody.hidden = true;
}
return cell;
}
if (nodeCount == 0 && indexPath.row > 0)
{
cell.hidden = true;
return cell;
}
if (nodeCount > 0)
{
uimg.hidden = false;
uimgresttile.hidden = false;
newsbody.hidden = true;
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
[newsbody setText:appRecord.Body];
if (!appRecord.appIcon)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
uimg.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
uimg.image = appRecord.appIcon;
}
if (!appRecord.appIconrestitle)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startRestitleIconDownload:appRecord forIndexPath:indexPath];
}
uimgresttile.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
uimgresttile.image = appRecord.appIconrestitle;
}
}
if ((unsigned long)indexPath.row == [self.entries count] - 1){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
^{
NewsFetchParseOperation *p = [[NewsFetchParseOperation alloc]init];
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
p.cat = appRecord.Category;
self.intindex = self.intindex + 1;
p.index = [NSString stringWithFormat:#"%d", (int)self.intindex];
p.lastid = appRecord.ids;
[p main];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
SubCategoryViewController *svc =[self.storyboard instantiateViewControllerWithIdentifier:#"SubCategory"];
NSArray *temp =[self.entries arrayByAddingObjectsFromArray:p.appRecordList];
self.entries = temp;
[self.tableView reloadData];
});
});
}
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell2";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
height += 1;
return height;
}
- (void)startIconDownload:(NewsFetchAppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
NewsFetchIconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader == nil)
{
iconDownloader = [[NewsFetchIconDownloader alloc] init];
iconDownloader.newsfetchappRecord = appRecord;
[iconDownloader setCompletionHandler:^{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIImageView *uimg = (UIImageView *)[cell.contentView viewWithTag:20];
uimg.image = appRecord.appIcon;
[self.imageDownloadsInProgress removeObjectForKey:indexPath];
}];
[self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
[iconDownloader startDownload];
}
}
- (void)startRestitleIconDownload:(NewsFetchAppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
NewsFetchRestitleIconDownloader *ResttitleiconDownloader = [self.imageRestitleDownloadsInProgress objectForKey:indexPath];
if (ResttitleiconDownloader == nil)
{
ResttitleiconDownloader = [[NewsFetchRestitleIconDownloader alloc] init];
ResttitleiconDownloader.newsfetchappRecord = appRecord;
[ResttitleiconDownloader setCompletionHandler:^{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIImageView *uimgresttile = (UIImageView *)[cell.contentView viewWithTag:23];
uimgresttile.image = appRecord.appIconrestitle;
[self.imageRestitleDownloadsInProgress removeObjectForKey:indexPath];
}];
[self.imageRestitleDownloadsInProgress setObject:ResttitleiconDownloader forKey:indexPath];
[ResttitleiconDownloader startDownload];
}
}
- (void)loadImagesForOnscreenRows
{
if ([self.entries count] > 0)
{
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!appRecord.appIcon)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
- (void)loadRestitleImagesForOnscreenRows
{
if ([self.entries count] > 0)
{
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!appRecord.appIconrestitle)
{
[self startRestitleIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
[self loadRestitleImagesForOnscreenRows];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
[self loadRestitleImagesForOnscreenRows];
}
#end
Edit:
In iphone if i scroll the the table it will freeze and jump most of time. even when
picture loaded properly. this problem never happen in simulator and only in real device.
i read most of article here base on "uitableview" lagging. most them suggest to use asnyc
method for downloading images. im using apple lazyloading sample method so i guess images
gets downloaded other than main thread.
think i have done till now is to comment most of code section by section and still lag
happend.
i even remove most part from Storyboard , but still lag happend.
You should delete all of your image download methods. Delete also scrollViewDidEndDragging and scrollViewDidEndDecelerating. I don't know why your heightForRowAtIndexPath is so complicated. Is every row a different size? If not use a simple case statement with the couple of cases you've got. Different height for each row can be a drag on resources.
Now for cellForRowAtIndexPath:
If the hidden not hidden stuff you are doing is for performance you should delete all of that.
Add AFNetworking to your project. If you are using cocaopods (you should) can add it with on line in your Podfile. It's good practice when developing with iOS to use libraries and AFNetworking is the best when it comes to getting stuff like images from a network.
#import "UIImageView+AFNetworking.h"
Now all your image work is done with one line of code (AFNetworking will handle all the caching and the performance related issues and the asynchronous stuff for you):
[uimg setImageWithURL:"http://blahbahblah.com" placeholderImage:someUIIMage]
I am having an app in which I am showing some data in my tableview as shown in the ScreenShot1 below.
Screenshot1.
Now I am having an imageview On my each tableview cell.
If I select any of the cell from tableview, I want an image on that selected cell as shown in screenshot2 below.
Screenshot2.
Now If I select any other cell form tableview. I want to set my imageview's image only on those selected cells as shown in Screenshot3 below.
Below is the code I am doing.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
lblRecipe = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 600, 32)];
lblRecipe.backgroundColor = [UIColor clearColor];
lblRecipe.font = [UIFont systemFontOfSize:20.0f];
[cell.contentView addSubview:lblRecipe];
checkedimg=[[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
[cell.contentView addSubview:checkedimg];
lblRecipe.text = [array objectAtIndex:indexPath.row];
return cell;
}
On Tableview's didselect method, what should i keep to have this kind of a functionality?
I searched a lot and there are lots of questions for this but couldn't find one for this.
So Please help me on this.
Thanks in advance.
You may be better off just subclassing UITableViewCell, as this would let you change the way the cells draw, and add a property or something of the sort to indicate this state.
To create the subclass, create a new file in Xcode, and select UITableViewCell as its superclass.
Then, within that subclass, you could implement a method called setStrikeThrough: like this that you can call on the cell you dequeue from the table:
- (void) setStrikeThrough:(BOOL) striked {
if(striked) {
// create image view here and display, if it doesn't exist
} else {
// hide image view
}
}
Then, in the view controller that holds the table, you'd call this in viewDidLoad to register your subclass with the table view:
[_tableView registerClass:[YourAmazingTableCell class] forCellReuseIdentifier:#"AmazingCellSubclass"];
You would then alter your tableView:cellForRowAtIndexPath: to be something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"AmazingCellSubclass";
YourAmazingTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[YourAmazingTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// here you would look up if this row should be selected
[cell setStrikeThrough:YES];
// Set up the remainder of the cell, again based on the row
cell.textLabel.text = #"chilli";
return cell;
}
Try this,
Add a NSMutableArray checkedCellArray, as property and alloc init.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UILabel *labelRecipe = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 600, 32)];
labelRecipe.backgroundColor = [UIColor clearColor];
labelRecipe.font = [UIFont systemFontOfSize:20.0f];
labelRecipe.tag = kRecipeTag;//a tag to label
[cell.contentView addSubview:labelRecipe];
UIImageView *checkedimg = [[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
[checkedimg setImage:[UIImage imageNamed:#"checked.png"];
checkedimg.tag = kCheckedImageTag;//a tag to imageView
[cell.contentView addSubview:checkedimg];
checkedimg.hidden = YES;
}
UILabel *labelRecipe = (UILabel *)[cell.contentView viewWithTag:kRecipeTag];
UIImageView *checkedimg = (UIImageView *)[cell.contentView viewWithTag:kCheckedImageTag];
if ([self.checkedCellArray containsObject:indexPath]) {
checkedimg.hidden = NO;
} else {
checkedimg.hidden = YES;
}
labelRecipe.text = [array objectAtIndex:indexPath.row];
return cell;
}
and in didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (![self.checkedCellArray containsObject:indexPath]) {
[self.checkedCellArray addObject:indexPath];
}
NSArray* rowsToReload = [NSArray arrayWithObjects:indexPath, nil];
[UITableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
}
Oky hear you can do like this
just subclass the tableview cell
in CustomCell.h file
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
#property (nonatomic,retain)UIImageView *dashImageView; //add a property of image view
#end
in CustomCell.m file
#import "CustomCell.h"
#implementation CustomCell
{
BOOL isCellSelected; //add this to check
}
#synthesize dashImageView = _dashImageView; //synthesize it
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
isCellSelected = NO;//initially set it no
_dashImageView = [[UIImageView alloc]initWithFrame:CGRectMake(self.bounds.origin.x + 15, self.bounds.origin.y + 10, self.bounds.size.width, 15.0f)];
_dashImageView.backgroundColor = [UIColor redColor];
_dashImageView.tag = 12345;
_dashImageView.hidden = YES;
[self.contentView addSubview:_dashImageView];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected)
{
UIImageView *dashImageVIew = (UIImageView *)[self viewWithTag:12345];
if(dashImageVIew)
{
if(!isCellSelected)
{
dashImageVIew.hidden = NO;
isCellSelected = YES;
}
else
{
dashImageVIew.hidden = YES;
isCellSelected = NO;
}
}
}
}
EDIT:2 *For selecting both section and row for the table view*
there is no change in the custom cell only change in the controller so that u hav to reflect what changes that u made to tableview cell i.e weather u select or deselect
since u want select section along with the selected row.(your requirement) there are various way to do that, but i go by using some model object which contains index section and row.
for that u need to create a subclass of NSObject and name it as MySelectedIndex then in
in MySelectedIndex.h file
#import <Foundation/Foundation.h>
#interface MySelectedIndex : NSObject<NSCoding>//to store and retrieve data like user defaults, for non-property list objects, confirms to NSCoding protocol
#property (nonatomic,retain) NSNumber *selectedRow;
#property (nonatomic,retain) NSNumber *selectedSection;
- (id)initWithSelectedRow:(NSNumber *)selRow andSelectedIndex:(NSNumber *)selSection;
#end
in MySelectedIndex.m file
#import "MySelectedIndex.h"
#implementation MySelectedIndex
#synthesize selectedSection = _selectedSection;
#synthesize selectedRow = _selectedRow;
- (id)initWithSelectedRow:(NSNumber *)selRow andSelectedIndex:(NSNumber *)selSection
{
self = [super init];
if(self)
{
_selectedRow = selRow;
_selectedSection = selSection;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_selectedRow forKey:#"ROW"];
[aCoder encodeObject:_selectedSection forKey:#"SECTION"];
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if(self)
{
_selectedRow = [aDecoder decodeObjectForKey:#"ROW"];
_selectedSection = [aDecoder decodeObjectForKey:#"SECTION"];
}
return self;
}
#end
now get back to controller where u are using the table
in .m file
import it #import "CustomCell.h"
and in the method
in viewController.m
#interface SampleViewController ()<UITableViewDataSource,UITableViewDelegate>
{
NSMutableArray *indexes;//to store in defaults
NSMutableArray *indexesRed;//to red from the defaults
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//...other stuff's
indexes = [[NSMutableArray alloc]init];//initilise your arrays
indexesRed = [[NSMutableArray alloc]init];
//after initilizing your array
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"SELECTED_CELLL"];
if(data != nil)
{
indexes = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[indexes retain];//you hav to retain the objects other wise u will get crash, make sure u will release it by proper memory mabagement (if u are not using ARC)
}
}
as u said u are using buttons to pop this viewcontroller so already u know where to place so put this in all the action methods(just replace where u are saving to user defaults )
and also read the comments that i put in the code
//put all these codes where u poping this viewcontroller
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:indexes];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"SELECTED_CELLL"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.navigationController popViewControllerAnimated:YES];
replace the cellForRowAtIndexPath by following code (i added in the below method)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath
{
CustomTabedCell *Cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(Cell == nil)
{
Cell = [[CustomTabedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
Cell.textLabel.text = #"Apple";
NSNumber *rowNum = [NSNumber numberWithInt:indexPath.row];
NSNumber *secNum = [NSNumber numberWithInt:indexPath.section];
__block BOOL isImageHidden = YES;
[indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)
{
if(obj.selectedRow == rowNum && obj.selectedSection == secNum)
{
isImageHidden = NO;
}
}];
Cell.dashImageView.hidden = isImageHidden;
[Cell.contentView bringSubviewToFront:Cell.dashImageView];//as i notised the red dash imageview appers below the text, but in your image it is appearing above the text so put this line to bring the imageview above the text if dont want commnent this
return Cell;
}
finally in the method didSelectRowAtIndexPath replace by following method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *selSection = [NSNumber numberWithInt:indexPath.section];
NSNumber *selRow = [NSNumber numberWithInt:indexPath.row];
if([indexes count] == 0)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else if ([indexes count] == 1)
{
MySelectedIndex *singleIndex = [indexes objectAtIndex:0];
if(singleIndex.selectedSection == selSection & singleIndex.selectedRow == selRow)
{
[indexes removeAllObjects];
}
else
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
}
else
{
__block BOOL addSelectedRow = NO;
__block int index = -1;
[indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop) {
if(!((obj.selectedRow == selRow) & (obj.selectedSection == selSection)))
{
addSelectedRow = YES;
}
else
{
index = idx;
addSelectedRow = NO;
*stop = YES;
}
}];
if(addSelectedRow)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else
{
if(index >= 0)
{
[indexes removeObjectAtIndex:index];
}
}
}
NSLog(#"%#",indexes.description);
[tableView reloadData];
}
edit for not able to select more than 13 row's
in viewDidLoad
do like this
indexes = [[NSMutableArray alloc]init];
indexesRed = [[NSMutableArray alloc]init];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"SELECTED_CELLL"];
if(data != nil)
{
indexes = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain]; //hear only u retain it
NSLog(#"%#",indexes.description);//check the description, how many objects are there in the array
NSLog(#"indexes->%d",[indexes count]);
}
//[indexes retain];//comment this
} //end of `viewDidLoad`
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTabedCell *Cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(Cell == nil)
{
Cell = [[CustomTabedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
Cell.textLabel.text = #"Apple";
__block BOOL isImageHidden = YES; //remove that __block qualifier
// __block NSInteger currentRow = indexPath.row;
// __block NSInteger currentSection = indexPath.section;
// [self.indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)
// {
// NSInteger rowNum = [obj.selectedRow integerValue];
// NSInteger secNum = [obj.selectedSection integerValue];
// if(rowNum == currentRow && secNum == currentSection)
// {
// isImageHidden = NO;
// }
// }];
//comment block code and use simple for loop, looping through each obj slightly faster
for(int k = 0;k < [indexes count];k++)
{
MySelectedIndex *seletedIndex = [indexes objectAtIndex:k];
NSInteger row = [seletedIndex.selectedRow integerValue];
NSInteger sec = [seletedIndex.selectedSection integerValue];
if(row == indexPath.row & sec == indexPath.section)
{
isImageHidden = NO;
}
}
Cell.dashImageView.hidden = isImageHidden;
[Cell.contentView bringSubviewToFront:Cell.dashImageView];//as i notised the red dash imageview appers below the text, but in your image it is appearing above the text so put this line to bring the imageview above the text if dont want commnent this
return Cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *selSection = [NSNumber numberWithInt:indexPath.section];
NSNumber *selRow = [NSNumber numberWithInt:indexPath.row];
if([indexes count] == 0)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else if ([indexes count] == 1)
{
MySelectedIndex *singleIndex = [indexes objectAtIndex:0];
NSInteger rowNumInInt = [singleIndex.selectedRow integerValue];
NSInteger sectionInInt = [singleIndex.selectedSection integerValue];
if(sectionInInt == indexPath.section & rowNumInInt == indexPath.row)
{
[indexes removeAllObjects];
}
else
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
}
else
{
BOOL addSelectedRow = NO;
int index = -1;
for(int j = 0; j < [indexes count];j++)
{
MySelectedIndex *selectedObj = [indexes objectAtIndex:j];
NSInteger rowInt = [selectedObj.selectedRow integerValue];
NSInteger sectionInt = [selectedObj.selectedSection integerValue];
if(!(rowInt == indexPath.row && sectionInt == indexPath.section))
{
addSelectedRow = YES;
}
else
{
index = j;
addSelectedRow = NO;
// *stop = YES;
}
}
if(addSelectedRow)
{
MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
[indexes addObject:selectedIndx];
}
else
{
if(index >= 0)
{
[indexes removeObjectAtIndex:index];
}
}
}
// [tableView reloadData];
NSLog(#"indexes count->%d",[indexes count]);//check each time by selecting and deselectin weateher it is working or not
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
thats it simple .. :)
hope this helps u .. :)
Try This it work good
#import "ViewController.h"
#interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
UITableView *menuTableView;
NSMutableArray *colorsArray,*tagvalueArray;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
menuTableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 60, 320, 404) style:UITableViewStyleGrouped];
menuTableView.delegate=self;
menuTableView.dataSource=self;
menuTableView.separatorColor=[UIColor grayColor];
[self.view addSubview:menuTableView];
NSArray *serverResponseArray=[[NSArray alloc]initWithObjects:#"red",#"yellow",#"pink",#"none", nil]; // consider this array as the information you receive from DB or server
colorsArray =[[NSMutableArray alloc]init];
tagvalueArray =[[NSMutableArray alloc]init];
for (int i=0; i<serverResponseArray.count; i++) {
[colorsArray addObject:serverResponseArray[i]];
[tagvalueArray addObject:#"0"];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return colorsArray.count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview];
}
cell.textLabel.text =colorsArray[indexPath.row];
if ([[tagvalueArray objectAtIndex:indexPath.row]intValue]==1) {
UIImageView *checkedimg=[[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
checkedimg.backgroundColor=[UIColor redColor];
[cell.contentView addSubview:checkedimg];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",colorsArray[indexPath.row]);
[tagvalueArray replaceObjectAtIndex:indexPath.row withObject:#"1"];
[menuTableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I am trying to implement https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
code for collection view.. Everything is working fine. But in cellForRowAtIndex method while re-loading of old cell the application is crashing. Have a look at code:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:
(NSInteger)section
{
if (self.galleryItemsArray) {
return [self.galleryItemsArray count];
}
else
{
return 0;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger nodeCount = [self.galleryItemsArray count];
static NSString* simpleTableIdentifier = #"SavedMessageCell_ID";
SavedMessagesCell *cell = [cv dequeueReusableCellWithReuseIdentifier:simpleTableIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[SavedMessagesCell alloc] initWithFrame:CGRectZero];
}
cell.textLabel.text = [NSString stringWithFormat:#"{%ld,%ld}", (long)indexPath.row, (long)indexPath.section];
if(nodeCount>0)
{
GalleryItemDS *item = [self.galleryItemsArray objectAtIndex:indexPath.row];
// Only load cached images; defer new downloads until scrolling ends
if (!item.imageOfItem)
{
if (gallery_collectionView.dragging == NO && gallery_collectionView.decelerating == NO)
{
[self startIconDownload:item forIndexPath:indexPath];
NSLog(#"%#",item.PhotoPath);
}
// if a download is deferred or in progress, return a placeholder image
cell.image.image = [UIImage imageNamed:#"Icon.png"];
}
else
{
NSLog(#"%#",[NSString stringWithFormat:#"{%ld,%ld}", (long)indexPath.row, (long)indexPath.section]);
NSLog(#"%#",item.PhotoPath);
**cell.image.image = item.imageOfItem; // Crashing here**
}
}
return cell;
}
// -------------------------------------------------------------------------------
// startIconDownload:forIndexPath:
// -------------------------------------------------------------------------------
- (void)startIconDownload:(GalleryItemDS *)galleryItem forIndexPath:(NSIndexPath *)indexPath
{
IconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader == nil)
{
iconDownloader = [[IconDownloader alloc] init];
iconDownloader.galleryItem = galleryItem;
[iconDownloader setCompletionHandler:^{
SavedMessagesCell *cell = (SavedMessagesCell *)[gallery_collectionView cellForItemAtIndexPath:indexPath];
// Display the newly loaded image
cell.image.image = galleryItem.imageOfItem;
// cell.backgroundColor = [UIColor colorWithPatternImage:galleryItem.imageOfItem];
// Remove the IconDownloader from the in progress list.
// This will result in it being deallocated.
[self.imageDownloadsInProgress removeObjectForKey:indexPath];
}];
[self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
[iconDownloader startDownload];
}
}
- (void)loadImagesForOnscreenRows
{
if ([self.galleryItemsArray count] > 0)
{
NSArray *visiblePaths = [gallery_collectionView indexPathsForVisibleItems];
for (NSIndexPath *indexPath in visiblePaths)
{
GalleryItemDS *appRecord = [self.galleryItemsArray objectAtIndex:indexPath.row];
if (!appRecord.imageOfItem)
// Avoid the app icon download if the app already has an icon
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
#pragma mark - UIScrollViewDelegate
// -------------------------------------------------------------------------------
// scrollViewDidEndDragging:willDecelerate:
// Load images for all onscreen rows when scrolling is finished.
// -------------------------------------------------------------------------------
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
}
}
// -------------------------------------------------------------------------------
// scrollViewDidEndDecelerating:
// -------------------------------------------------------------------------------
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
}
Please help me in it.
I am writing a google reader application and have been trying to create the settings table view with UISwitch. Below is the complete code sequence:
#implementation Settings
#synthesize rowImage;
#synthesize ViewPushed;
#synthesize alreadySignedIn;
#synthesize syncStartupSwitch;
#synthesize confirmMarkSwitch;
#synthesize landscapeModeSwitch;
#synthesize appBadgeSwitch;
#synthesize fontSwitch;
#synthesize newItemsSwitch;
#pragma mark -
#pragma mark View lifecycle
static SEL syncStartup;
static SEL markAsReadConfirm;
static SEL landscapeMode;
static SEL appBadge;
static SEL fontSettings;
static SEL newItemsFirstSel;
+(void) initialize{
syncStartup = #selector(syncAtStartup:);
markAsReadConfirm = #selector (confirmMarkAsRead:);
landscapeMode = #selector (landscapeMode:);
appBadge = #selector (appBadgeSetting:);
fontSettings = #selector (largeFontSetting:);
newItemsFirstSel = #selector (newItemFirst:);
}
-(void) newItemFirst:(id)sender {
if ([sender isOn]) {
newItemsSwitch = YES;
}else {
newItemsSwitch = NO;
}
}
-(void) syncAtStartup:(id)sender {
if ([sender isOn]) {
syncStartupSwitch = YES;
}else {
syncStartupSwitch = NO;
}
}
-(void) confirmMarkAsRead:(id)sender{
if ([sender isOn]) {
confirmMarkSwitch = YES;
}else {
confirmMarkSwitch = NO;
[self.tableView reloadData];
}
}
-(void) landscapeMode:(id)sender{
if([sender isOn]) {
landscapeModeSwitch = YES;
}else {
landscapeModeSwitch = NO;
}
}
-(void) appBadgeSetting:(id)sender{
if([sender isOn]) {
appBadgeSwitch = YES;
}else {
appBadgeSwitch = NO;
}
}
-(void) largeFontSetting:(id)sender{
if ([sender isOn]) {
[UIFont systemFontOfSize:32];
fontSwitch = YES;
NSLog(#"YES");
}else {
fontSwitch = NO;
NSLog(#"YES");
}
}
/*
-(void) saveLastViewedItem{
[plistData setValue:[[[UIApplication sharedApplication]delegate]currentItemID]forKey:keyLastItemID];
[plistData setValue:[[[[[[[UIApplication sharedApplication]delegate]navController]navController]topViewController]delegate]tag]forKey:keyLastItemTag];
}
-(void) save {
[self saveLastViewedItem];
BOOL success = [plistData writeToFile:[docsPath stringByAppendingPathComponent:plistName] atomically:YES];
if (!success) {
NSLog(#"FAILED saving plist");
}else {
dbg_s(#"saved data:%# to file: %#", plistData, [docsPath stringByAppendingPathComponent:plistName]);
}
}
-(void) load{
dbg(#"loading plist data from path: %#", [docsPath stringByAppendingPathComponent:plistName]);
plistData = [[NSMutableDictionary dictionaryWithContentsOfFile:[docsPath stringByAppendingPathComponent:plistName]]retain];
if(!plistData){
NSLog(#"FAILED loading plist");
plistData = [[NSMutableDictionary dictionary] retain];
}
dbg_s(#"Loaded plist data", plistData);
dbg_s("%#", plistData);
[self removeDeprecatedProperties];
[self loadFeedList];
}
-(void) removeDeprecatedProperties{
for (NSString * deprecatedProperty in deprecatedProperties){
[plistData removeObjectForKey:deprecatedProperty];
}
}
-(void) reloadFeedList{
[self loadFeedList];
[self setUIElements];
}
-(NSArray *) loadFeedList {
NSString *contents = [NSString stringWithContentsOfFile:[docsPath stringByAppendingPathComponent:#"tagList"]encoding:NSUTF8StringEncoding error:nil];
id result;
if(!contents) {
dbg(#"no feed list loaded");
result = nil;
}else {
NSArray *originalList = [contents componentsSeparatedByString:#"\n"];
NSMutableArray *feedList = [NSMutableArray arrayWithCapacity:[originalList count]];
for (NSString *feed in originalList) {
NSString *trimmedFeed = [feed stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if([feed length] > 0){
[feedList addObject:trimmedFeed];
}
}
result = feedList;
}
[possibleTags release];
possibleTags = [result retain];
return result;
}
-(NSArray *)feedList {
return possibleTags;
}
-(NSArray *) activeTagList {
id tags = [self tagList];
NSArray *result = [NSMutableArray arrayWithCapacity:[tags count]];
for (NSString *tag in tags) {
if([possibleTags containsObject:tag]) {
[result arrayByAddingObject:tag];
}
}
return result;
}
-(id) init{
self =[super init];
plistName = #"config.plist";
if (openLinksInSegmentValues == nil)
openLinksInSegmentValues = [[NSArray alloc] initWithObjects:openLinksInAskMeValue, openLinksInSafariValue, openLinksIniReaderValue, nil];
if (deprecatedProperties == nil)
deprecatedProperties = [[NSArray alloc] initWithObjects:#"openInSafari", nil];
[self docsPath];
[self load];
return self;
}
*/
- (void)viewDidLoad {
syncSwitch=[[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
readSwitch=[[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
landscapeSwitch=[[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
badgeSwitch=[[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
largeFontSwitch=[[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
newItemsFirstSwitch =[[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
//switcher = [[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
NSString *loginData;
NSError *keychainError;
NSString *checkUsername= [SFHFKeychainUtils getPasswordForUsername:#"Username" andServiceName:#"iReader" error:&keychainError];
NSString *checkPassword = [SFHFKeychainUtils getPasswordForUsername:#"Password" andServiceName:#"iReader" error:&keychainError];
if (checkPassword == nil || checkUsername == nil) {
alreadySignedIn = NO;
loginData = #"Sync Settings";
} else {
alreadySignedIn = YES;
loginData = #"Logout";
}
if(ViewPushed == NO) {
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel_Clicked:)] autorelease];
}
listOfItems = [[NSMutableArray alloc] init];
NSArray *syncSettingsToLoad = [NSArray arrayWithObjects:loginData, nil];
NSDictionary *syncSettingsToLoadDict = [NSDictionary dictionaryWithObject:syncSettingsToLoad forKey:#"Settings"];
NSArray *generalSetting = nil;
generalSetting = [NSArray arrayWithObjects:#"Sync at Startup",#"Confirm Mark as Read", #"Landscape Mode", #"Cache Settings",nil];
NSMutableDictionary *generalSettingsDict = [NSMutableDictionary dictionaryWithObject:generalSetting forKey:#"Settings"];
NSArray *appearanceSettings = [NSArray arrayWithObjects:#"New Items First", #"App Icon Badge", #"Large Font", nil];
NSDictionary *appearanceSettingsDict = [NSDictionary dictionaryWithObject:appearanceSettings forKey:#"Settings"];
NSArray *sharingSettings = [NSArray arrayWithObjects:#"Customize Sharing Options", nil];
NSDictionary *sharingSettingsDict = [NSDictionary dictionaryWithObject:sharingSettings forKey:#"Settings"];
NSArray *advancedSettings = [NSArray arrayWithObjects:#"Advanced Options", nil];
NSDictionary *advancedSettingsDict = [NSDictionary dictionaryWithObject:advancedSettings forKey:#"Settings"];
[listOfItems addObject:syncSettingsToLoadDict];
[listOfItems addObject:generalSettingsDict];
[listOfItems addObject:appearanceSettingsDict];
[listOfItems addObject:sharingSettingsDict];
[listOfItems addObject:advancedSettingsDict];
self.title =#"Settings";
// Uncomment the following line to preserve selection between presentations.
//self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
[super viewDidLoad];
}
//defaultDatabase = [[userPrefs valueForKey:MAPref_DefaultDatabase] retain];
-(void) cancel_Clicked:(id)sender
{
[self.navigationController dismissModalViewControllerAnimated:YES];
}
- (void)viewWillAppear:(BOOL)animated {
//[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return [listOfItems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSDictionary *dictionary = [listOfItems objectAtIndex:section];
NSArray *array = [dictionary objectForKey:#"Settings"];
return [array count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:
(NSInteger) section {
if (section == 0) {
return #"Sync Settings";
}
if (section == 1) {
return #"General Options";
}
if (section == 2) {
return #"Appearance Options";
}
if (section == 3){
return #"Sharing Options";
}
if (section == 4){
return #"Advanced Options";
}
return nil;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//NSLog(#"This is what we are looking for %# %#", checkUsername, checkPassword);
// Configure the cell...
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array =[dictionary objectForKey:#"Settings"];
NSString * cellValue = [array objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (indexPath.section == 0 && indexPath.row == 0) {
static NSString *SomeIdentifierA = #"SomeIdentifierA";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierA];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierA] autorelease];
cell.accessoryType = UITableViewCellSelectionStyleBlue;
}
cell.textLabel.text =cellValue;
return cell;
}
else if (indexPath.section ==1 && indexPath.row ==0) {
static NSString *SomeIdentifierB = #"SomeIdentifierB";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierB];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierB] autorelease];
[syncSwitch addTarget:self action:#selector(syncAtStartup:) forControlEvents:UIControlEventValueChanged];
//[cell.contentView addSubview:syncSwitch];
cell.accessoryView = syncSwitch;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//cell.reuseIdentifier = #"Cell1";
}
cell.textLabel.text =#"Sync at Startup";
return cell;
}
else if(indexPath.section == 1 && indexPath.row == 1){
static NSString *SomeIdentifierC = #"SomeIdentifierC";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierC];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierC] autorelease];
[readSwitch addTarget:self action:#selector(confirmMarkAsRead:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = readSwitch;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text =#"Confirm Mark as Read";
return cell;
}
else if(indexPath.section == 1 && indexPath.row == 2){
static NSString *SomeIdentifierD = #"SomeIdentifierD";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierD];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierD] autorelease];
[landscapeSwitch addTarget:self action:#selector(landscapeMode:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = landscapeSwitch;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text =#"Landscape Mode";
return cell;
}
else if (indexPath.section == 1 && indexPath.row == 3) {
static NSString *SomeIdentifierE = #"SomeIdentifierE";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierE];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierE] autorelease];
cell.accessoryType = UITableViewCellSelectionStyleBlue;
}
cell.textLabel.text =#"Cache Settings";
return cell;
}
else if (indexPath.section == 1 && indexPath.row == 4) {
static NSString *SomeIdentifierJ = #"SomeIdentifierJ";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierJ];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierJ] autorelease];
cell.accessoryType = UITableViewCellSelectionStyleBlue;
}
cell.textLabel.text =#"Caches";
return cell;
}
else if(indexPath.section == 2 && indexPath.row == 0){
static NSString *SomeIdentifierN = #"SomeIdentifierF";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierN];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierN] autorelease];
[newItemsFirstSwitch addTarget:self action:#selector(newItemFirst:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = newItemsFirstSwitch;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text =#"App Icon Badge";
return cell;
}
else if(indexPath.section == 2 && indexPath.row == 1){
static NSString *SomeIdentifierF = #"SomeIdentifierF";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierF];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierF] autorelease];
[badgeSwitch addTarget:self action:#selector(appBadgeSetting:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = badgeSwitch;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text =#"App Icon Badge";
return cell;
}
else if(indexPath.section == 2 && indexPath.row == 2){
static NSString *SomeIdentifierG = #"SomeIdentifierG";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierG];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierG] autorelease];
[largeFontSwitch addTarget:self action:#selector (largeFontSetting:) forControlEvents:UIControlEventValueChanged];
//[largeFontSwitch addTarget:self action:#selector(largeFontSetting:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = largeFontSwitch;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text =#"Large Font Size";
return cell;
}
else if (indexPath.section == 3 && indexPath.row == 0) {
static NSString *SomeIdentifierH = #"SomeIdentifierH";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierH];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierH] autorelease];
cell.accessoryType = UITableViewCellSelectionStyleBlue;
}
cell.textLabel.text =#"Customize Sharing Options";
return cell;
}
else if (indexPath.section == 4 && indexPath.row == 0) {
static NSString *SomeIdentifierI = #"SomeIdentifierI";
// This could be some custom table cell class if appropriate
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SomeIdentifierI];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SomeIdentifierI] autorelease];
cell.accessoryType = UITableViewCellSelectionStyleBlue;
}
cell.textLabel.text =#"Advanced Options";
return cell;
}
//switcher.on = [[NSUserDefaults standardUserDefaults]boolForKey:#"Settings"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:13];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.section ==0){
if (alreadySignedIn == NO) {
if(indexPath.section == 0 && ivControllerCell == nil ){
[tableView reloadData];
ivControllerCell = [[GoogleClientLogin alloc] initWithNibName:#"GoogleClientLogin" bundle:[NSBundle mainBundle]];
ivControllerCell.ViewPushed = YES;
//Push the view controller to the top of the stack.
[self.navigationController pushViewController:ivControllerCell animated:YES];
[ivControllerCell release];
ivControllerCell = nil;
}
}
if (alreadySignedIn ==YES) {
NSError *keyChainEmpty;
[SFHFKeychainUtils deleteItemForUsername:#"Username" andServiceName:#"iReader" error:&keyChainEmpty];
[SFHFKeychainUtils deleteItemForUsername:#"Password" andServiceName:#"iReader" error:&keyChainEmpty];
ivControllerCell = [[GoogleClientLogin alloc] initWithNibName:#"GoogleClientLogin" bundle:[NSBundle mainBundle]];
ivControllerCell.ViewPushed = YES;
[self.navigationController pushViewController:ivControllerCell animated:YES];
}
}
}
-(void) removeSelfFromWindow
{/*
if(self.view.superview){
[UIView beginAnimations:#"curldown" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:NO];
[self.view.superview removeFromSuperview];
}
[UIView commitAnimations];
*/}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
/*static Settings * _standardSettings = nil;
+(Settings *)standardSettings
{
if (_standardSettings == nil)
_standardSettings = [[Settings alloc] init];
return _standardSettings;
}*/
-(void) setUIElements {
[landscapeSwitch setOn:[self landscapeModeSwitch]];
//[feedList setSelectedFeeds:[self taglist]];
}
- (void)dealloc {
[self save];
[plistData release];
[plistName release];
[super dealloc];
}
#end
I am getting the following error when I start scrolling the table view.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType addTarget:action:forControlEvents:]: unrecognized selector sent to instance 0x5f463e0'
Can somebody please help me with this error?
Cheers
Don't autorelease the switches when you alloc them. After those lines you don't own any of those objects.
syncSwitch=[[UISwitch alloc] initWithFrame:CGRectZero];
Release them in the dealloc method
[syncSwitch release];