How to Access Particular view of a pageControl viewController? - iphone

Hi I m creating a project where multiple Images Loading from Server With some like Count and Comment Count and a Button to like the image. I m showing the individual Images With using a Slider Controller like PageControl.
this is My code for Showing the View
-(UIView*)reloadView:(DPSliderView *)sliderView viewAtIndex:(NSUInteger)idx
{
_loading_view.hidden=TRUE;
if (idx < [photos count]) {
NSDictionary *item = [photos objectAtIndex:idx];
PhotoView *v = [[PhotoView alloc] init];
v.photoIndex = idx;
v.imageView.imageURL = [DPAPI urlForPhoto:item[#"photo_220x220"]];
NSString *placename1 = [item valueForKeyPath:#"spotting.item.name"];
NSString *firstCapChar1 = [[placename1 substringToIndex:1] capitalizedString];
NSString *cappedString1 = [placename1 stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:firstCapChar1];
v.spotNameLabel.text = cappedString1;
NSString *placename = [item valueForKeyPath:#"spotting.place.name"];
NSString *firstCapChar = [[placename substringToIndex:1] capitalizedString];
NSString *cappedString = [placename stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:firstCapChar];
NSString *place1=[NSString stringWithFormat:#"%#",cappedString];
NSString *address=[NSString stringWithFormat:#"%#",[item valueForKeyPath:#"spotting.place.address"]];
NSString *location_str3 = [NSString stringWithFormat:#"# %#, %#",place1,address];
int cap_len=[place1 length];
int address_lenth=[address length];
ZMutableAttributedString *str = [[ZMutableAttributedString alloc] initWithString:location_str3
attributes:[NSDictionary dictionaryWithObjectsAndKeys:
[[FontManager sharedManager] zFontWithName:#"Lucida Grande" pointSize:12],
ZFontAttributeName,
nil]];
[str addAttribute:ZFontAttributeName value:[[FontManager sharedManager] zFontWithName:#"Lucida Grande" pointSize:12] range:NSMakeRange(0, cap_len+3)];
[str addAttribute:ZForegroundColorAttributeName value:[UIColor colorWithRed:241/255.0f green:73.0/255.0f blue:2.0/255.0f alpha:1.0]range:NSMakeRange(0, cap_len+3)];
[str addAttribute:ZForegroundColorAttributeName value:[UIColor colorWithRed:128.0/255.0f green:121.0/255.0f blue:98.0/255.0f alpha:1.0]range:NSMakeRange(cap_len+4, address_lenth)];
v.placefontlabel.zAttributedText=str;
v.likesCountLabel.text = [NSString stringWithFormat:#"%i", [item[#"likes_count"] intValue]];
if ([_device_lang_str isEqualToString:#"es"])
{
v.shightingsLabel.text = [NSString stringWithFormat:NSLocalizedString(#"%i Vistas", nil), [item[#"sightings_count"] intValue]];
}
else
{
v.shightingsLabel.text = [NSString stringWithFormat:NSLocalizedString(#"%i Sightings", nil), [item[#"sightings_count"] intValue]];
}
if ([nolocationstr isEqualToString:#"YES"])
{
v.distanceLabel.text =[NSString stringWithFormat:#"%.2f km", [item[#"distance"] floatValue]];
}
else
{
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:[[item valueForKeyPath:#"spotting.place.lat"]floatValue] longitude:[[item valueForKeyPath:#"spotting.place.lng"] floatValue]];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:[_explore_lat_str floatValue] longitude:[_explore_lng_str floatValue]];
NSString *lat_laong=[NSString stringWithFormat:#"%f",[location1 distanceFromLocation:location2]];
int km=[lat_laong floatValue]*0.001;
NSString *distancestr=[NSString stringWithFormat:#"%d km",km];
float dist=[distancestr floatValue];
v.distanceLabel.text = [NSString stringWithFormat:#"%.2f km", dist];
}
if (![item[#"likes"] boolValue]) {
v.likeButton.enabled = YES;
v.likeButton.tag = idx;
[v.likeButton setImage:[UIImage imageNamed:#"like_new.png"] forState:UIControlStateNormal];
[v.likeButton addTarget:self action:#selector(likeAction:) forControlEvents:UIControlEventTouchUpInside];
}
else
{
v.likeButton.tag = idx;
[v.likeButton setImage:[UIImage imageNamed:#"like_new1.png"] forState:UIControlStateNormal];
}
NSArray *guides = item[#"guides"];
if ([guides count] > 0) {
NSString *guideType = [[guides objectAtIndex:0] valueForKey:#"type"];
UIImage *guidesIcon = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png", guideType]];
v.guideButton.hidden = NO;
v.guideButton.tag = idx;
[v.guideButton setImage:guidesIcon forState:UIControlStateNormal];
[v.guideButton addTarget:self action:#selector(guideAction:) forControlEvents:UIControlEventTouchUpInside];
}
v.shareButton.tag = idx;
[v.shareButton addTarget:self action:#selector(shareAction:) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(photoTapGesture:)];
[v addGestureRecognizer:tapGesture];
[tapGesture release];
return [v autorelease];
} else {
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"sc_img.png"]];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
indicator.center = CGPointMake(CGRectGetMidX(iv.bounds), 110);
[indicator startAnimating];
[iv addSubview:indicator];
[indicator release];
return [iv autorelease];
}
}
Now My question is :
If i will Click on Like Button , Then i have to change the button image as well as like count. I can able to Change the Button Image By This Method
[sender setImage:[UIImage ImageNamed:#"image.png"]];
But How can I change the Like count of the Label ? How can i access the Particular label of the View ? I have assigned the tag But , I dont know how to assign it.I dont want to Reload Whole Slider as the Photo are loading from Network (Remote Server) . Thanks for your Time.

Just keep a reference to the label and update that.
// #interface
#property (nonatomic, strong) UILabel *myLabel;
// #implementation
_myLabel.text = #"Whatever.";
If you have multiple labels, set the tags when you create your views
newView.tag = sequenceNumber +100;
And then update
-(void)updateLabelWithTag:(NSInteger)tag {
UILabel *label = (UILabel*) [self.scrollView viewWithTag:tag];
label.text = #"Whatever.";
}

Related

UIScrollView updating/loading wrongly

Im making a preview in my ViewController that all my Picked images in imagePicker will be in my scrollView,
Yes, I was able to make a preview of it in thumbnail, But when I'm logging it in my debugger, it seems to be that everytime my viewDidAppear, it also reAdds the scrollView, so the images count is being added again, making it harder to delete in view due to overlaping of the images. What I needed is to just refresh the scrollview whenever the view appears and when I'm adding a new image/s.
Here is a sneak preview of those codes I'm having problems for a long time:
- (id) initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
_images = [[NSMutableArray alloc] init];
_thumbs = [[NSMutableArray alloc] init];
}
return self;
}
- (void)addImage:(UIImage *)image {
[_images addObject:image];
[_thumbs addObject:[image imageByScalingAndCroppingForSize:CGSizeMake(60, 60)]];
[self createScrollView];
}
- (void) createScrollView {
[scrollView setNeedsDisplay];
int row = 0;
int column = 0;
for(int i = 0; i < _thumbs.count; ++i) {
UIImage *thumb = [_thumbs objectAtIndex:i];
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(column*60+10, row*60+10, 60, 75);
[button setImage:thumb forState:UIControlStateNormal];
[button addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
button.tag = i;
[scrollView addSubview:button];
if (column == 4) {
column = 0;
row++;
} else {
column++;
}
}
[scrollView setContentSize:CGSizeMake(300, (row+1) * 60 + 10)];
}
- (void)viewDidLoad
{
self.slotBg = [[UIView alloc] initWithFrame:CGRectMake(43, 370, 310, 143)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.slotBg.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor grayColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[self.slotBg.layer insertSublayer:gradient atIndex:0];
[self.view addSubview:self.slotBg];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f,0.0f,300.0f,130.0f)];
[slotBg addSubview:self.scrollView];
}
- (void)viewDidAppear:(BOOL)animated
{
[_thumbs removeAllObjects];
for(int i = 0; i <= 100; i++)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"Images%d.png", i]];
if([[NSFileManager defaultManager] fileExistsAtPath:savedImagePath]){
[self addImage:[UIImage imageWithContentsOfFile:savedImagePath]];
}
}
}
Help would be much appreciated.
And would using this be much of help, removing then adding. Or is this a way to just completely remove/delete all those subview completely, then REadd?
Thanks for those whose gonna help.
And could this be helpful? Thankyou
for(UIView *subview in [scrollView subviews]) {
if([subview isKindOfClass:[UIView class]]) {
[subview removeFromSuperview];
} else {
}
}
DELETE:
- (void)deleteItem:(id)sender {
_clickedButton = (UIButton *)sender;
UIAlertView *saveMessage = [[UIAlertView alloc] initWithTitle:#""
message:#"DELETE?"
delegate:self
cancelButtonTitle:#"NO"
otherButtonTitles:#"YES", nil];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"YES"]) {
NSLog(#"YES was selected.");
UIButton *button = _clickedButton;
[button removeFromSuperview];
[_images objectAtIndex:button.tag];
[_images removeObjectAtIndex:button.tag];
[_images removeObject:button];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"Images%lu.png", button.tag]];
[fileManager removeItemAtPath: fullPath error:NULL];
NSLog(#"image removed");
}
}
Here is a working example : Google Code
I wrote out the code, and I have this. It will align the view to be 5 wide, and however tall it has to be, and the scrollview will change height.
You will need to create a new NSMutableArray named _buttons that will contain a list of your buttons.
- (void)addImage:(UIImage *)imageToAdd {
[_images addObject:imageToAdd];
[_thumbs addObject:[imageToAdd imageByScalingAndCroppingForSize:CGSizeMake(60, 60)]];
int row = floor(([views count] - 1) / 5);
int column = (([views count] - 1) - (row * 5));
UIImage *thumb = [_thumbs objectAtIndex:[_thumbs count]-1];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(column*60+10, row*60+10, 60, 60);
[button setImage:thumb forState:UIControlStateNormal];
[button addTarget:self action:#selector(deleteItem:) forControlEvents:UIControlEventTouchUpInside];
button.tag = [views count] - 1;
// This is the title of where they were created, so we can see them move.s
[button setTitle:[NSString stringWithFormat:#"%d, %d", row, column] forState:UIControlStateNormal];
[_buttons addObject:button];
[scrollView addSubview:button];
// This will add 10px padding on the bottom as well as the top and left.
[scrollView setContentSize:CGSizeMake(300, row*60+20+60)];
}
- (void)deleteItem:(id)sender {
UIButton *button = (UIButton *)sender;
[button removeFromSuperview];
[views removeObjectAtIndex:button.tag];
[_buttons removeObjectAtIndex:button.tag];
[self rearrangeButtons:button.tag];
}
- (void)rearrangeButtons:(int)fromTag {
for (UIButton *button in _buttons) {
// Shift the tags down one
if (button.tag > fromTag) {
button.tag -= 1;
}
// Recalculate Position
int row = floor(button.tag / 5);
int column = (button.tag - (row * 5));
// Move
button.frame = CGRectMake(column*60+10, row*60+10, 60, 60);
if (button.tag == [_buttons count] - 1) {
[scrollView setContentSize:CGSizeMake(300, row*60+20+60)];
}
}
}
Note: In the rearrangeButtons method, it is possible to animate the changes.
Here is the code to rearrange the files:
- (void)rearrangeButtons:(int)fromTag {
for (UIButton *button in _buttons) {
// Shift the tags down one
if (button.tag > fromTag) {
// Create name string
NSString *imageName = [NSString stringWithFormat:#"images%i.png", button.tag];
// Load image
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFile = [paths objectAtIndex:0];
NSSting *oldFilePath = [documentFile stringByAppendingPathComponent:imageName];
NSData *data = [[NSData alloc] initWithContentsOfFile:oldFilePath];
button.tag -= 1;
// Save the image with the new tag/name
NSString *newImageName = [NSString stringWithFormat:#"images%i.png", button.tag];
NSString *newFilePath = [documentFile stringByAppendingPathComponent:newImageName];
[data writeToFile:newFilePath atomically:YES];
// Delete the old one
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *err = nil;
if (![fileManager removeItemAtPath:file error:&err]) {
// Error deleting file
}
}
// Recalculate Position
int row = floor(button.tag / 5);
int column = (button.tag - (row * 5));
// Move
button.frame = CGRectMake(column*60+10, row*60+10, 60, 60);
if (button.tag == [_buttons count] - 1) {
[scrollView setContentSize:CGSizeMake(300, row*60+20+60)];
}
}
}

UIScrollView not loading/updating properly

Im having problem with my UISCrollView, UIScrollVIew is in my View2Controller, my UIScrollView has thumbnail of images, which I imported from my ImagePicker picked images(multiple/single images). I have put my [self createScrollView]; in viewDidAppear, So at my first load of the view only the UIScrollView, obviously because I havent picked images yet. So after I picked its not updating in my view. But my images.count are updating in the my debugger. It's not updating in View, but when I go to another ViewController then return again to View2Controller, it loads the images in my UIScrollView,then when I add again images it's not updating. Why is it like that?.
- (void)addImage:(UIImage *)image {
[_images addObject:image];
[_thumbs addObject:[image imageByScalingAndCroppingForSize:CGSizeMake(60, 60)]];
}
- (void) createScrollView {
[scrollView setNeedsDisplay];
int row = 0;
int column = 0;
for(int i = 0; i < _thumbs.count; ++i) {
UIImage *thumb = [_thumbs objectAtIndex:i];
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(column*60+10, row*60+10, 60, 75);
[button setImage:thumb forState:UIControlStateNormal];
[button addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
button.tag = i;
[scrollView addSubview:button];
if (column == 4) {
column = 0;
row++;
} else {
column++;
}
}
[scrollView setContentSize:CGSizeMake(300, (row+1) * 60 + 10)];
}
- (void)viewDidAppear:(BOOL)animated
{
[self createScrollView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.slotBg = [[UIView alloc] initWithFrame:CGRectMake(43, 370, 310, 143)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.slotBg.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor grayColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[self.slotBg.layer insertSublayer:gradient atIndex:0];
[self.view addSubview:self.slotBg];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f,0.0f,300.0f,130.0f)];
[slotBg addSubview:self.scrollView];
for(int i = 0; i <= 100; i++)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"oneSlotImages%d.png", i]];
NSLog(#"savedImagePath=%#",savedImagePath);
if([[NSFileManager defaultManager] fileExistsAtPath:savedImagePath]){
[self addImage:[UIImage imageWithContentsOfFile:savedImagePath]];
NSLog(#"file exists");
}
}
NSLog(#"Count : %d", [_images count]);
}
EDIT: (In this part, the image can't be deleted from the view. But in my NSDocumentDirectory it is deleted, )
- (IBAction)buttonClicked:(id)sender {
_clickedButton = (UIButton *)sender;
UIAlertView *saveMessage = [[UIAlertView alloc] initWithTitle:#""
message:#"DELETE IMAGE?"
delegate:self
cancelButtonTitle:#"NO"
otherButtonTitles:#"YES", nil];
[saveMessage show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"YES"]) {
NSLog(#"YES was selected.");
UIButton *button = _clickedButton1;
[button removeFromSuperview];
[_images1 objectAtIndex:button.tag];
[_images1 removeObjectAtIndex:button.tag];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"firstSlotImages%lu.png", button.tag]];
[fileManager removeItemAtPath: fullPath error:NULL];
NSLog(#"image removed");
}
viewDidAppear: is only called once you go to a view. So when you are 'adding' the images you are only adding them to the _images array, they are not displayed because you are not adding them to the screen. They are displayed when you leave the view and come back because viewDidAppear: is called again.
To fix this, use addImage: to also add it to the current view.
- (void)addImage:(UIImage *)image {
int row = ?;
int column = ?;
[_images addObject:image];
[_thumbs addObject:[image imageByScalingAndCroppingForSize:CGSizeMake(60, 60)]];
UIImage *thumb = [_thumbs objectAtIndex:_thumbs.count-1];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(column*60+10, row*60+10, 60, 75);
[button setImage:thumb
forState:UIControlStateNormal];
[button addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
button.tag = _thumbs.count-1;
[scrollView addSubview:button];
}
Only problem of course is how to determine the placement, aka column and row. You can do this by getting the last thumb's frame and figuring out where to place it according to screen bounds.
Another Fix
- (void)addImage:(UIImage *)image {
[_images addObject:image];
[_thumbs addObject:[image imageByScalingAndCroppingForSize:CGSizeMake(60, 60)]];
[self createScrollView];
}
You need to call createScrollView after you have updated your array of images. Maybe try moving [self createScrollView]; to the end of your viewDidLoad method? Either way, you need to call createScrollView after you have added all of your images.

iphone+UIscrollview or to use uitableview to display image in matrix format

I want to display the image(which comes from webservice) the format such that the output in the screen appears like below image:-
Now the logic i had implemented is,i had added the image in uiscrollview.
with the below logic:-
for (int j=0;j<9;j++) {
for (int i=0; i<[mainRestaurantArray count];i++) {
if ([[[mainRestaurantArray objectAtIndex:i] valueForKey:#"Image"] isKindOfClass:[UIImage class]]) {
[CombineArray addObject:[mainRestaurantArray objectAtIndex:i]];
//NSLog(#"cnt=>%d array==>%#",cnt,[CombineArray objectAtIndex:cnt]);
UIButton* btn = [[UIButton alloc]init];
btn.tag = cnt;
btn.frame = CGRectMake(15+(cnt%5)*60, 15+(cnt/5)*60,Width,Height);
btn.backgroundColor = [UIColor greenColor];
[btn setBackgroundImage:[[CombineArray objectAtIndex:cnt] valueForKey:#"Image"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(Buttonclick:) forControlEvents:UIControlEventTouchUpInside];
[ScrlPhotos addSubview:btn];
[btn release];
cnt++;
}
}
[mainRestaurantArray release];
counter++;
[self urlcalled];//The function which calls the webservice
}
//}
ScrlPhotos.contentSize = CGSizeMake(320, ([CombineArray count]/5.0)*60+25);
The function which does the webservice is below:-
-(void)urlcalled{
#try
{
if (rangeDistance == nil) {
rangeDistance =#"100";
}
urlstring[0]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Gym&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[1]=[NSString stringWithFormat:#"http://www.google.com/maps?q=resort&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[2]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Tourist place&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[3]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Hotels&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[4]=[NSString stringWithFormat:#"http://www.google.com/maps?q=shopping Mall&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[5]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Industries&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[6]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Shopping_mall&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[7]=[NSString stringWithFormat:#"http://www.google.com/maps?q=garden&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[8]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Religious Place&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[9]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Restaurants&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
NSLog(#"conte==>%d urlstring[counter]==>%#",counter,urlstring[counter]);
NSString *str = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlstring[counter]]];
str1 = [str substringFromIndex:9];
//NSLog(#"===>%#",str1);
NSArray *array = [str1 componentsSeparatedByString:#"overlays:"];
NSString *str2 = [array objectAtIndex:1];
NSString *finalUpperStr = [str2 substringFromIndex:21];
array1 = [finalUpperStr componentsSeparatedByString:#"},panel:"];
NSString *strF = [array1 objectAtIndex:0];
NSArray *arrayF = [strF componentsSeparatedByString:#"{id:"];
///////....................this object will change as require in for loop .............................//
mainRestaurantArray = [[NSMutableArray alloc] init];
for (int i=1; i<[arrayF count]-5; i++) {
NSString *strF12 = [arrayF objectAtIndex:i];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
NSArray *aryF23 = [strF12 componentsSeparatedByString:#"latlng:{"];
//NSLog(#"%#",[aryF23 objectAtIndex:1]);
NSString *strF23 = [aryF23 objectAtIndex:1];
NSArray *ar = [strF23 componentsSeparatedByString:#"},image:"];
//NSLog(#"%#",[ar objectAtIndex:0]);
NSString *strLat = [ar objectAtIndex:0];
NSArray *arrayLat = [strLat componentsSeparatedByString:#","];
NSString *strFLat = [[arrayLat objectAtIndex:0] substringFromIndex:4];
NSString *strLong = [[arrayLat objectAtIndex:1] substringFromIndex:4];
//NSLog(#"Lati = %# Longi = %#" , strFLat , strLong);
[dic setValue:strFLat forKey:#"Latitude"];
[dic setValue:strLong forKey:#"Longitude"];
NSString *strLAdd = [ar objectAtIndex:1];
NSArray *arrayLAdd = [strLAdd componentsSeparatedByString:#"laddr:"];
//NSLog(#"%#",[arrayLAdd objectAtIndex:1]);
NSString *strLAdd1 = [arrayLAdd objectAtIndex:1];
NSArray *arrayLAdd1 = [strLAdd1 componentsSeparatedByString:#"geocode:"];
// NSLog(#"%#",[arrayLAdd1 objectAtIndex:0]);
NSString *strAddres = [[arrayLAdd1 objectAtIndex:0] stringByReplacingOccurrencesOfString:#"\"" withString:#""];
//NSLog(#"%#",strAddres);
[dic setValue:strAddres forKey:#"Address"];
NSString *strName = [arrayLAdd1 objectAtIndex:1];
NSArray *arrayName = [strName componentsSeparatedByString:#"name:"];
NSString *strName1 = [[arrayName objectAtIndex:1]stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *arrayName1 = [strName1 componentsSeparatedByString:#"infoWindow:"];
[dic setValue:[arrayName1 objectAtIndex:0] forKey:#"Name"];
// for image load .. 07Dec..
NSString *strImage= [arrayF objectAtIndex:i];
NSRange range = [strImage rangeOfString:#"photoUrl"];
if(range.location == NSNotFound){
NSLog(#"Not found");
[dic setValue:#"" forKey:#"Image"];
}else{
NSArray *arrayImage = [strImage componentsSeparatedByString:#"photoUrl:"];
NSString *strImage1 = [arrayImage objectAtIndex:1];
NSArray *arrayImage1 = [strImage1 componentsSeparatedByString:#",photoType:"];
NSString *strfindImage = [[arrayImage1 objectAtIndex:0] stringByReplacingOccurrencesOfString:#"\"" withString:#""];
myImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:strfindImage]]];
[dic setValue:myImage forKey:#"Image"];
}
[mainRestaurantArray addObject:dic];
if (i==20) {
break;
}
}
}
#catch (NSException * e)
{
NSLog(#"NSException==>%#",e);
}
}
But the problem i am facing is the image is displayed after completing the loop at 10 times.
I want to display the image parallely as it comes from webservice,so that time taken should be less..
Is there any way out..
Please help me.
Use UIImageView+cacheWeb.. it makes lazy loading a lot easier
http://hackemist.com/SDWebImage/doc/Categories/UIImageView+WebCache.html

Iphone cellForRowAtIndexPath Jerky when scrolling asynchronously problem

I've released my app and noticed the jerkyness when scrolling in the CellForRowAtIndexPath, this is because i'm rendering an image from an JSON Feed via a URL. I've searched the internet and found a few examples and this one i've almost got working. The problem is when it renders the images don't match the correct title. Can someone please have a look and see what if i'm doing something obviously wrong.
Anyway here is my code:
- (void)displayImage:(UIImage *)image {
[photo setImage:image];
}
-(void)loadImage:(NSString *)url {
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
[imageData release];
[self performSelectorOnMainThread:#selector(displayImage:) withObject:image waitUntilDone:NO];
}
CellForRowAtIndexPath Methord
#define DATELABEL_TAG 1 #define MAINLABEL_TAG 2 #define PHOTO_TAG 3 UIImageView *photo;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MainNewsCellIdentifier = #"MainNewsCellIdentifier";
UILabel *mainLabel, *dateLabel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: MainNewsCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MainNewsCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
dateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,15.0,170.0,15.0)] autorelease];
dateLabel.tag = DATELABEL_TAG;
dateLabel.font = [UIFont systemFontOfSize:10.0];
dateLabel.textAlignment = UITextAlignmentLeft;
dateLabel.textColor = [UIColor darkGrayColor];
dateLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
[cell.contentView addSubview:dateLabel];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,28.0,170.0,60.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont boldSystemFontOfSize:14.0];
mainLabel.textColor = [UIColor blackColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
mainLabel.numberOfLines = 0;
[cell.contentView addSubview:mainLabel];
photo = [[[UIImageView alloc] initWithFrame:CGRectMake(190.0,15.0,85.0,85.0)] autorelease];
photo.tag = PHOTO_TAG;
photo.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:photo];
}
else {
dateLabel = (UILabel *)[cell.contentView viewWithTag:DATELABEL_TAG];
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
}
NSUInteger row = [indexPath row];
NSDictionary *stream = (NSDictionary *) [dataList objectAtIndex:row];
NSString *title = [stream valueForKey:#"title"];
NSString *titleString = #"";
if( ! [title isKindOfClass:[NSString class]] )
{
titleString = #"";
}
else
{
titleString = title;
}
CGSize maximumSize = CGSizeMake(180, 9999);
UIFont *dateFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize dateStringSize = [titleString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:mainLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(15.0, 28.0, 170.0, dateStringSize.height);
mainLabel.frame = dateFrame;
mainLabel.text = titleString;
dateLabel.text = [stream valueForKey:#"created"];
NSString *i = [NSString stringWithFormat:#"http://www.domain.co.uk/images/stories/%#", [stream valueForKey:#"image"]];
photo.image = [UIImage imageNamed:#"i_digital_media.png"];
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(loadImage:)
object:i];
[queue addOperation:operation];
[operation release];
return cell;}
By the time that your image is loaded, the photo variable is pointed to a different photo :)
You need to pass both the loaded image and the UIImageView you want to update back - try using a NSDictionary to pass variables between threads :
- (void)displayImage:(NSDictionary *)info {
[[info objectForKey:#"photo"] setImage:[info objectForKey:#"image"]];
}
-(void)loadImage:(NSDictionary *)info {
NSString *imagePath = [info objectForKey:#"imagePath"];
UIImageView *photo = [info objectForKey:#"photo"];
// Load the image
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
[imageData release];
// Pass it back to the main thread
NSDictionary *mainThreadInfo = [NSdictionary dictionaryWithObjectAndKeys:image, #"image", photo, #"photo", nil];
[self performSelectorOnMainThread:#selector(displayImage:) withObject:mainThreadInfo waitUntilDone:YES];
}
so now, your operation will pass the photo and the image data back to the main thread. Create the operation like this :
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:i, #"imagePath", photo, #"photo", nil];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(loadImage:)
object:info];
And get rid of the global photo variable :)

NSScrollView gives error when scrolling "-[CALayer isEqual:]: message sent to deallocated instance"

I'm trying to fix my code but I have no idea why I'm getting these errors:
modifying layer that is being finalized - 0x11818240
2010-09-10 02:35:53.022 iPhone Monkey Curling[1606:207] modifying layer that is being finalized - 0x11818240
2010-09-10 02:35:53.023 iPhone Monkey Curling[1606:207] modifying layer that is being finalized - 0x11818240
2010-09-10 02:35:54.671 iPhone Monkey Curling[1606:207] *** -[CALayer isEqual:]: message sent to deallocated instance 0x11818240
This happens when my all_score_table scroll view has had an attempt to scroll it (Crashes immediately on scroll attempt). Here is my code which sets the scroll views:
NSMutableArray * scores_data = [[first_data componentsSeparatedByString: #"\n"] mutableCopy];
if ([scores_data count] != 3) {
UIAlertView *connection_alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Malformed server response." delegate:nil cancelButtonTitle:#"Close" otherButtonTitles: nil];
[connection_alert show];
[connection_alert release];
return;
}
if([[scores_data objectAtIndex:0] isEqual:#""]){
[scores_data replaceObjectAtIndex:0 withObject:#"No scores for today,"];
}
if([[scores_data objectAtIndex:1] isEqual:#""]){
[scores_data replaceObjectAtIndex:1 withObject:#"No scores this week,"];
}
if([[scores_data objectAtIndex:2] isEqual:#""]){
[scores_data replaceObjectAtIndex:2 withObject:#"No scores,"];
}
[scores_data replaceObjectAtIndex:0 withObject: [[scores_data objectAtIndex:0] componentsSeparatedByString: #";"]];
[scores_data replaceObjectAtIndex:1 withObject: [[scores_data objectAtIndex:1] componentsSeparatedByString: #";"]];
[scores_data replaceObjectAtIndex:2 withObject: [[scores_data objectAtIndex:2] componentsSeparatedByString: #";"]];
NSLog(#"scores_data");
if (todays_scores_table){
//One of the tables exist so all of them must. Release them for renewal.
[todays_scores_table release];
[week_scores_table release];
[all_scores_table release];
[online_scores_pages release]; //release pages also
}
NSLog(#"1");
todays_scores_table = [[UIScrollView alloc] initWithFrame:CGRectMake(10, 110, 295, 300)];
week_scores_table = [[UIScrollView alloc] initWithFrame:CGRectMake(330, 110, 295, 300)];
all_scores_table = [[UIScrollView alloc] initWithFrame:CGRectMake(650, 110, 295, 300)];
todays_scores_table.contentSize = CGSizeMake(205, 60 + 40*[[scores_data objectAtIndex:0] count]);
week_scores_table.contentSize = CGSizeMake(205, 60 + 40*[[scores_data objectAtIndex:1] count]);
all_scores_table.contentSize = CGSizeMake(205, 60 + 40*[[scores_data objectAtIndex:2] count]);
NSLog(#"2");
NSArray * score_data;
NSString * path = [[NSBundle mainBundle] pathForResource: #"single_score_image" ofType:#"png"];
NSData * data = [[NSData alloc] initWithContentsOfFile:path];
UIImage * background_image = [[UIImage alloc] initWithData:data];
UIImageView * background_view;
UIImage * header_image;
if(submission){
path = [[NSBundle mainBundle] pathForResource: #"scores_header" ofType:#"png"];
[data release];
NSLog(#"3");
data = [[NSData alloc] initWithContentsOfFile:path];
header_image = [[UIImage alloc] initWithData:data];
}
UIImageView * header_view;
int offset;
UILabel * label;
NSLog(#"4");
UIScrollView * tables[3] = {todays_scores_table,week_scores_table,all_scores_table};
online_scores_pages = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
online_scores_pages.contentSize = CGSizeMake(960, 420);
online_scores_pages.pagingEnabled = YES; //Act like iphone home page
UIImage * title_image;
UIImageView * title_view;
NSLog(#"5");
//border for scores table
[data release];
path = [[NSBundle mainBundle] pathForResource: #"score_table_border" ofType:#"png"];
data = [[NSData alloc] initWithContentsOfFile:path];
UIImage * border_image = [[[UIImage alloc] initWithData:data] autorelease];
UIImageView * score_table_border;
for (int a = 0; a < 3; a++) {
if(submission){ //Only do header when submitting score
header_view = [[UIImageView alloc] initWithImage: header_image];
header_view.frame = CGRectMake(10, 10, 275, 30);
NSLog(#"5A");
[tables[a] addSubview: header_view];
[header_view release];
label = [[UILabel alloc] initWithFrame:CGRectMake(25, 10, 245, 30)];
label.backgroundColor = [UIColor clearColor];
NSLog(#"5B");
NSString * end;
NSLog(#"5C");
if ([[scores_data objectAtIndex:a+3] characterAtIndex:0] == '1'){
end = #"st";
}else if ([[scores_data objectAtIndex:a+3] characterAtIndex:0] == '2'){
end = #"nd";
}else if ([[scores_data objectAtIndex:a+3] characterAtIndex:0] == '3'){
end = #"rd";
}else{
end = #"th";
}
NSArray * pos_data = [[scores_data objectAtIndex:a+3] componentsSeparatedByString: #"/"];
label.text = [NSString stringWithFormat: #"You came %#%# from %# scores.",[pos_data objectAtIndex:0],end,[pos_data objectAtIndex:1]];
[tables[a] addSubview:label];
NSLog(#"5E");
[label release];
NSLog(#"6");
}
for (int x = 0; x < [[scores_data objectAtIndex:a] count]; x++){
score_data = [[[scores_data objectAtIndex:a] objectAtIndex:x] componentsSeparatedByString: #","];
//Image for each score
offset = 50 + 40*x;
background_view = [[UIImageView alloc] initWithImage: background_image];
background_view.frame = CGRectMake(10, offset, 275, 30); //Reposition
[tables[a] addSubview: background_view];
[background_view release];
//Add score position
label = [[UILabel alloc] initWithFrame:CGRectMake(10, offset, 30, 30)];
label.backgroundColor = [UIColor clearColor];
label.text = [NSString stringWithFormat: #"%i",x+1];
label.textAlignment = UITextAlignmentCenter;
[tables[a] addSubview:label];
[label release];
NSLog(#"7 %# \n\n %#",score_data,scores_data);
//Add name
label = [[UILabel alloc] initWithFrame:CGRectMake(55, offset, 190, 30)];
label.backgroundColor = [UIColor clearColor];
label.text = [score_data objectAtIndex:0];
[tables[a] addSubview:label];
[label release];
//Add score
label = [[UILabel alloc] initWithFrame:CGRectMake(55, offset, 225, 30)];
label.backgroundColor = [UIColor clearColor];
label.text = [NSString stringWithFormat: #"%#",[score_data objectAtIndex:1]];
label.textAlignment = UITextAlignmentRight;
[tables[a] addSubview:label];
[label release];
NSLog(#"8");
}
//Add title
switch (a) {
case 0:
path = [[NSBundle mainBundle] pathForResource: #"todays_scores_title" ofType:#"png"];
break;
case 1:
path = [[NSBundle mainBundle] pathForResource: #"week_scores_title" ofType:#"png"];
break;
case 2:
path = [[NSBundle mainBundle] pathForResource: #"all_scores_title" ofType:#"png"];
break;
}
[data release];
data = [[NSData alloc] initWithContentsOfFile:path];
title_image = [[[UIImage alloc] initWithData:data] autorelease];
title_view = [[[UIImageView alloc] initWithImage: title_image] autorelease];
title_view.frame = CGRectMake(25 + 320*a, 15, 270, 75); //Reposition and resize
[online_scores_pages addSubview:title_view];
NSLog(#"9");
//Add table
score_table_border = [[UIImageView alloc] initWithImage: border_image];
score_table_border.frame = CGRectMake(320*a, 100, 320, 320); //Reposition
[online_scores_pages addSubview: tables[a]];
[online_scores_pages addSubview: score_table_border];
[score_table_border release];
}
[data release];
if(submission){
[header_image release];
[header_view release];
}
[background_image release];
[background_view release];
[self addSubview: online_scores_pages];
[online_scores_pages becomeFirstResponder];
Thank you for any help. It is much appreciated.
The only iEqual: that I see is in the series of tests:
if([[scores_data objectAtIndex:0] isEqual:#""]){
if([[scores_data objectAtIndex:1] isEqual:#""]){
if([[scores_data objectAtIndex:2] isEqual:#""]){
So looking back at scores_data I see:
MutableArray * scores_data = [[first_data componentsSeparatedByString: #"\n"] mutableCopy];
Is first_data a NSString? If so I'm suspecting that componentsSeparatedByString will return a array of strings. This means that when you do [scores_data objectAtIndex:?] you will get a string.
The isEqual: at this point then looks wrong. Instead of isEqual: you should probably use isEqualToString:.
However, you're seeing a problem with accessing a deallocated object. That implies an excessive number of releases and I can't see that here.
I don't like that call to "mutableCopy" that you are using. I'd prefer to be more explicit in the initialisation:
MutableArray * scores_data = [[NSMutableArray alloc] initWithArray:[first_data componentsSeparatedByString: #"\n"]];
Finally! I found the problem.
I had this call - [background_view release]; once to many. I remove it at the end as it was being released when necessary in the for loop.
Now it works!!!!