I am trying to add a subview on ImageView control, I think, i have alloc view and dealloc view properly.This is my code.
for(int Count =0; Count < [list count]; Count++)
{
MapCallout *callout = [list objectAtIndex:Count];
CGSize constSize = { 700.0f, 40.0f };
NSString * sTmp = [callout.Name stringByAppendingString:#"WW"];
CGSize textSize = [sTmp sizeWithFont:[UIFont fontWithName:#"Arial-BoldMT" size:25.0] constrainedToSize:constSize lineBreakMode:UILineBreakModeClip];
int xValue = callout.X;
int yValue = callout.Y;
int position = 0;
UIImage *calloutImage;
if(callout.Direction==0)
{
calloutImage=[UIImage newImageFromResource:#"arrow-0.png"];
callout.Y=callout.Y-3; position= -3;
}
else if(callout.Direction==1)
{
calloutImage=[UIImage newImageFromResource:#"arrow-1.png"];
callout.Y=callout.Y-3; position= -3;
}
else if(callout.Direction==2)
{
callout.Y=callout.Y + 2;
calloutImage=[UIImage newImageFromResource:#"arrow_2.png"];
position= +2;
}
CalloutButton *calloutButton = nil;
int arraySize = [dequeueReusableCallout count] - 1;
if(Count > arraySize)
{
calloutButton = [[[CalloutButton alloc]initWithFrame:CGRectMake(xValue,
self.tapDetectingImageView.frame.origin.y + yValue ,
textSize.width,40)] autorelease];
[calloutButton setDelegate:self];
[dequeueReusableCallout addObject:calloutButton];
}
calloutButton = [dequeueReusableCallout objectAtIndex:Count];
[calloutButton setFrame:CGRectMake(xValue,
self.tapDetectingImageView.frame.origin.y + yValue ,
textSize.width,40)] ;
[calloutButton setBackgroundImage:calloutImage andText:callout.Name andYvalue:position];
calloutButton.tag = callout.ID;
calloutButton.ViewMapType = [callout.calloutType intValue];
calloutButton.isLive = callout.isLive;
calloutButton.isAnimated = callout.isAnimated;
[self.tapDetectingImageView addSubview:calloutButton];
}
//Callout Button Method
-(void) setBackgroundImage:(UIImage*)image andText:(NSString*)text andYvalue:(double)Y
{
if(!btnCallout)
btnCallout = [[UIButton alloc] init];
[btnCallout setFrame:CGRectMake(0, -Y, self.frame.size.width, self.frame.size.height)];
[btnCallout setBackgroundImage:image forState:UIControlStateNormal];
[btnCallout addTarget:self action:#selector(CalloutTouch:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btnCallout];
if(!lblCallout)
lblCallout = [[UILabel alloc] init];
[lblCallout setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
lblCallout.backgroundColor = [UIColor clearColor];
lblCallout.font = [UIFont systemFontOfSize:42.0];
lblCallout.userInteractionEnabled = NO;
lblCallout.text = text;
lblCallout.textAlignment = UITextAlignmentCenter;
lblCallout.font = [UIFont fontWithName:#"Arial-BoldMT" size:25.0];
[self addSubview:lblCallout];
}
[self viewForZoomingInScrollView:self.mapScrollView];
}
If i call this method method multi-times, memory warning is occur and app get crash.
Here, [self.tapDetectingImageView addSubview:calloutButton]; I if comment this statement, it is working properly. Please let me know where i am wrong.
You should call [calloutButton release] after you add it to the dequeueReusableCallout array since the array now has a retain on the newly allocated instance
Related
I have some generic generated ImageViews in a scrollView each of these images have 2 gestureRecognizer for single/double tapping on the ImageView. Now my problem is how to identify whether the ImageView was tapped for first or second time. In some scenarios it's easy to use the tag of an ImageView, but I have two different gestureRecognizer on each ImageView and every gestureRecognizer uses a different identification method based on the tag number, to identify the image.
Here I generate the ImageViews dynamically:
-(void) initLevels{
_level = [Level alloc];
_unit = [Unit alloc];
self->_units = [[NSMutableArray alloc] init];
_keys = [[NSMutableArray alloc] init]
;
int x = 0;
int y = 0;
int i = 0;
for (NSObject *object in self->_levels) {
if ([object isKindOfClass:_level.class] && i != 0) {
x = x + MARGIN_RIGHT + OBJECT_WIDTH;
y = 0;
}
else if ([object isKindOfClass:_unit.class]){
_unit = (Unit *) object;
[self->_units addObject:_unit.description];
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.box];
[imageView setFrame:CGRectMake(x, y, OBJECT_WIDTH, BOX_HEIGHT)];
imageView.highlighted = TRUE;
imageView.tag = i; //when this is not outlined the gestureRecognizer for singleTapping works but on the other hand the double tap gestureRecognizer just works for the first object, because its' tag is set on 0.
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(unitDoubleTapped:)];
doubleTapGesture.numberOfTapsRequired = 2;
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:doubleTapGesture];
UITapGestureRecognizer *singleTapGesture =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(unitSingleTapped:)];
singleTapGesture.numberOfTapsRequired = 1;
//telling the singleTapGesture to fail the doubleTapGesture, so both doesn't fire at the same time
[singleTapGesture requireGestureRecognizerToFail:doubleTapGesture];
[imageView addGestureRecognizer:singleTapGesture];
UILabel *labelHeadline = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, 220, 20)];
[labelHeadline setFont:[UIFont boldSystemFontOfSize:12]];
labelHeadline.textAlignment = NSTextAlignmentCenter;
[labelHeadline setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0]];
labelHeadline.text = _unit.headline;
labelHeadline.numberOfLines = 0;
[labelHeadline sizeToFit];
UILabel *labelPrice = [LabelUtils deepLabelCopy:labelHeadline withText:[NSString stringWithFormat:#"Price: %#",_unit.price] withFrame:NO];
[labelPrice setTextAlignment:NSTextAlignmentLeft];
[labelPrice setFrame:CGRectMake(labelHeadline.frame.origin.x, labelHeadline.frame.origin.y + labelHeadline.frame.size.height + 2, 220, 20)];
UILabel *labelCRM = [LabelUtils deepLabelCopy:labelHeadline withText:[NSString stringWithFormat:#"CRM: %#", _unit.crm] withFrame:NO];
[labelCRM setTextAlignment:NSTextAlignmentLeft];
[labelCRM setFrame:CGRectMake(labelPrice.frame.origin.x, labelPrice.frame.origin.y + labelPrice.frame.size.height + 2, 220, 20)];
UITextView *textView= [[UITextView alloc] initWithFrame:CGRectMake(0,0, OBJECT_WIDTH, OBJECT_HEIGHT)];
[textView addSubview:labelHeadline];
[textView addSubview:labelPrice];
[textView addSubview:labelCRM];
[textView setUserInteractionEnabled:NO];
[textView setEditable:NO];
textView.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0];
textView.textAlignment = NSTextAlignmentLeft;
[imageView addSubview:textView];
[_scrollView addSubview:imageView];
y = y + MARGIN_BOTTOM + BOX_HEIGHT;
}
[self->_keys addObject:[NSNumber numberWithInt:i]];
i++;
}//remove the last keys which are to much in the _keys array
while ([self->_keys count] > ([self->_units count])) {
[_keys removeLastObject];
i--;
}
self.contents = [NSDictionary dictionaryWithObjects:self->_units forKeys:_keys];
}
Here is the code for the two gesture Recognizer
-(void)unitDoubleTapped:(UIGestureRecognizer *)gestureRecognizer{
self->_unitViewForDoubleTapIdentification = (UIImageView *)gestureRecognizer.view;
switch (self->_unitViewForDoubleTapIdentification.tag) {
case 0:
[_unitViewForDoubleTapIdentification setHighlightedImage:self.transparentBox];
self->_unitViewForDoubleTapIdentification.tag = 1;
break;
case 1:
[_unitViewForDoubleTapIdentification setHighlightedImage:self.box];
self->_unitViewForDoubleTapIdentification.tag = 0;
break;
default:
break;
}
}
and Here the singleTap
- (IBAction)unitSingleTapped:(id)sender {
[self dismissAllPopTipViews];
UIGestureRecognizer *gestureRecognizer = [UIGestureRecognizer alloc];
gestureRecognizer = (UIGestureRecognizer *)sender;
UIImageView *imageView = [[UIImageView alloc] init];
imageView = (UIImageView *)gestureRecognizer.view;
if (sender == _currentPopTipViewTarget) {
// Dismiss the popTipView and that is all
self.currentPopTipViewTarget = nil;
}
NSString *contentMessage = nil;
UIImageView *contentView = nil;
NSNumber *key = [NSNumber numberWithInt:imageView.tag];
id content = [self.contents objectForKey:key];
if ([content isKindOfClass:[NSString class]]) {
contentMessage = content;
}
else {
contentMessage = #"A large amount ot text in this bubble\najshdjashdkgsadfhadshgfhadsgfkasgfdasfdhasdkfgaodslfgkashjdfg\nsjfkasdfgkahdjsfghajdsfgjakdsfgjjakdsfjgjhaskdfjadsfgjdsfahsdafhjajdskfhadshfadsjfhadsjlfkaldsfhfldsa\ndsfgahdsfgajskdfgkafd";
}
NSArray *colorScheme = [_colorSchemes objectAtIndex:foo4random()*[_colorSchemes count]];
UIColor *backgroundColor = [colorScheme objectAtIndex:0];
UIColor *textColor = [colorScheme objectAtIndex:1];
CMPopTipView *popTipView;
if (contentView) {
popTipView = [[CMPopTipView alloc] initWithCustomView:contentView];
}
else {
popTipView = [[CMPopTipView alloc] initWithMessage:contentMessage];
}
[popTipView presentPointingAtView:imageView inView:self.view animated:YES];
popTipView.delegate = self;
popTipView.disableTapToDismiss = YES;
popTipView.preferredPointDirection = PointDirectionUp;
if (backgroundColor && ![backgroundColor isEqual:[NSNull null]]) {
popTipView.backgroundColor = backgroundColor;
}
if (textColor && ![textColor isEqual:[NSNull null]]) {
popTipView.textColor = textColor;
}
popTipView.animation = arc4random() % 2;
popTipView.has3DStyle = (BOOL)(arc4random() % 2);
popTipView.dismissTapAnywhere = YES;
[popTipView autoDismissAnimated:YES atTimeInterval:3.0];
[_visiblePopTipViews addObject:popTipView];
self.currentPopTipViewTarget = sender;
}
Hope you can help me, thanks in advance.
that's a lot of code to go through.. but I add more identifiers to UIViews (ie other than the tag identifier) by using obj-c runtime associative references..
So this is a category I attach to my UIView:
#import "UIView+Addons.h"
#import <objc/runtime.h>
#define kAnimationDuration 0.25f
#implementation UIView (Addons)
static char infoKey;
static char secondaryInfoKey;
-(id)info {
return objc_getAssociatedObject(self, &infoKey);
}
-(void)setInfo:(id)info {
objc_setAssociatedObject(self, &infoKey, info, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(id)secondaryInfo {
return objc_getAssociatedObject(self, &secondaryInfoKey);
}
-(void)setSecondaryInfo:(id)info {
objc_setAssociatedObject(self, &secondaryInfoKey, info, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#end
here is an example of my own code where I use the above to address a problem similar to the one you're facing:
if (![[view info] boolValue]) { // not selected?
self.moveToFolderNumber = [view secondaryInfo];
[view setInfo:#YES];
}
In one of the projects I'm working on, I have a UIScrollView that has a lot of buttons and labels that resemble movie theater seats that the user can tap to select seats for them to buy. Is it possible to zoom the UIScrollView? I have already declared the UIScrollViewDelegate, set the delegate to self, set the minimum and maximum zoom scale but I'm having issues with the viewForZoomingInScrollView and scrollViewDidEndZooming methods. I tried to return my scrollview on the viewForZoomingInScrollView method but it crashes.
Here's some of the code:
- (void) renderSeatMapOnScreen
{
int x_offset_row = 10;
int y_offset_row = 25;
int x_offset_col = 30;
int y_offset_col = 0;
int scrollview_w = 0;
int scrollview_h = 0;
NSString *row_name = #"";
int tag_index = 0;
NSMutableArray *seat_map_table = [seat_map_xml seats_map];
NSString *seat_available_str = [seat_avail_xml seat_available];
HideNetworkActivityIndicator();
NSLog(#"Seats available = %#", seat_available_str);
NSArray *seats_avail = [seat_available_str componentsSeparatedByString:#";"];
int ROW_COL_OFFSET = 25;
for (int row = 0; row < [seat_map_table count]; row++)
{
UILabel * rowlabel = [[UILabel alloc] init];
rowlabel.frame = CGRectMake(x_offset_row , y_offset_row, 22, 22);
SeatMapDeclaration *rowmap = [seat_map_table objectAtIndex:row];
rowlabel.text = rowmap.rows;
[scrollview addSubview:rowlabel];
row_name = [NSString stringWithFormat:#"%#", rowmap.rows];
NSArray *seat = [rowmap.rowmap componentsSeparatedByString:#";"];
NSLog(#"row[%i] = %#", row, rowmap.rowmap);
if (row == 0)
{
scrollview_w = [seat count] * ROW_COL_OFFSET + y_offset_row;
total_column = [seat count];
total_row = [seat_map_table count];
}
x_offset_col = 30 ;
y_offset_col = y_offset_row ;
for (int column = 0; column < [seat count]; column++)
{
if (([[seat objectAtIndex:column] rangeOfString:#"a("].location != NSNotFound)
|| ([[seat objectAtIndex:column] isEqualToString:#""]))
{
CGRect myImageRect = CGRectMake(x_offset_col, y_offset_col, 22, 22);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:myImageRect];
[imageView setImage:[UIImage imageNamed:#"noseat.png"]];
[scrollview addSubview:imageView];
}
else if ([[seat objectAtIndex:column] rangeOfString:#"b("].location != NSNotFound)
{
CGRect myImageRect = CGRectMake(x_offset_col, y_offset_col, 22, 22);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:myImageRect];
imageView.image = [UIImage imageNamed:#"noseat.png"];
[scrollview addSubview:imageView];
}
else
{
NSString *status = [NSString stringWithFormat:#"%#%#", row_name, [seat objectAtIndex:column]];
BOOL matchedFound = NO;
for (int i = 0; i < [seats_avail count]; i++)
{
if ([[seats_avail objectAtIndex:i] isEqualToString:status])
{
matchedFound = YES ;
break ;
}
}
if (matchedFound == YES)
{
UIButton * seat_btn = [UIButton buttonWithType:UIButtonTypeCustom];
[seat_btn setBackgroundImage:[UIImage imageNamed:#"seatavailable.png"] forState:UIControlStateNormal];
[seat_btn setBackgroundImage:[UIImage imageNamed:#"seatactive.png"] forState:UIControlStateSelected];
seat_btn.frame = CGRectMake(x_offset_col, y_offset_col, 22, 22);
tag_index = [[seat objectAtIndex:column] intValue];
[seat_btn setTitle:[seat objectAtIndex:column] forState:UIControlStateNormal];
seat_btn.titleLabel.font = [UIFont fontWithName:#"Helvetica" size:12.0];
seat_btn.tag = tag_index + row * 100;
[seat_btn addTarget:self
action:#selector(checkboxButton:)
forControlEvents:UIControlEventTouchUpInside];
[scrollview addSubview:seat_btn];
}
else
{
CGRect myImageRect = CGRectMake(x_offset_col, y_offset_col, 22, 22);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:myImageRect];
imageView.image = [UIImage imageNamed:#"seat_not_available.png"];
[scrollview addSubview:imageView];
}
}
x_offset_col += ROW_COL_OFFSET ;
NSString *data = #"";
[seatControl addObject:data];
}
y_offset_row += ROW_COL_OFFSET;
}
UILabel *screenlabel = [[UILabel alloc] init];
screenlabel.frame = CGRectMake((scrollview_w-300)/2, 3, 300, 15);
screenlabel.text = #"Screen";
screenlabel.backgroundColor = [UIColor blackColor];
screenlabel.textColor = [UIColor whiteColor] ;
screenlabel.font = [UIFont fontWithName:#"Helvetica" size:10.0];
screenlabel.textAlignment = UITextAlignmentCenter;
[scrollview addSubview:screenlabel];
scrollview_h = y_offset_row + ROW_COL_OFFSET;
// Adjust scroll view
[scrollview setContentSize:CGSizeMake(scrollview_w, scrollview_h )];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
NSLog(#"1");
return scrollview;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
NSLog(#"2");
}
In:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
NSLog(#"1");
return scrollview;
}
you are not supposed to return the UIScrollView itself, rather its subview that you would like to scroll/zoom.
If you have many subviews, I would suggest creating a container view for all of them that you return from viewForZoomingInScrollView; instead of adding your seats to the scrollview itself you would then add them to the container view.
If you want to zoom to a certain seat in the UIScrollView, you should use zoomToRect: animated:. You can specify a certain rectangle (i.e. the seat) to which you would like to zoom in on.
Zooming only works when you implement the viewForZoomingInScrollView: delegate callback.
UIImageView *tempImage = [[UIImageView alloc]initWithImage:[UIImage imageWithData:data]];
self.imageView = tempImage;
scrollView.contentSize = CGSizeMake(imageView.frame.size.width , imageView.frame.size.height);
scrollView.maximumZoomScale = 1;
scrollView.minimumZoomScale = .37;
scrollView.clipsToBounds = YES;
scrollView.delegate = self;
[scrollView addSubview:imageView];
scrollView.zoomScale = .37;
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)inScroll {
return imageView;
}
I have a class that implements "UIView" and inside - (void)drawRect:(CGRect)rect method I add some custom buttons to self. Inside a UIViewController I declare an instance of this view and i add it to self.view.
If i do this in - (void)viewDidLoad, everything works perfect, but if I create a method that is called when I push a button, and add that view to self.view, the buttons background is displayed after a few second. Till then only the name of the button appears written in white.
What do i do wrong?
Regards
#implementation CustomButton
#synthesize isPressed, buttonViewNumber;
- (id)initWithFrame:(CGRect)frame
title:(NSString *)title
tag:(int)tag
{
self = [super initWithFrame:frame];
if (self) {
[self setTitle:title forState:UIControlStateNormal];
[self setTag:tag];
self.titleLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.contentEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
[self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[self setBackgroundImage:[[UIImage imageNamed:#"btn_white_add.png"] stretchableImageWithLeftCapWidth:20.0 topCapHeight:0.0] forState:UIControlStateNormal];
[self addTarget:self action:#selector(didSelect) forControlEvents:UIControlEventTouchUpInside];
self.isPressed = NO;
}
return self;
}
#implementation ButtonsView
#synthesize listOfButtons;
- (id)initWithFrame:(CGRect)frame bundle:(NSArray *)data
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
listOfNames = [[NSArray arrayWithArray:data] retain];
listOfButtons = [[NSMutableArray alloc] init];
currentViewNumber = 0;
viewNumber = 0;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGSize maximumLabelSize = CGSizeMake(300,24);
UIFont *buttonFont = [UIFont fontWithName:#"Helvetica" size:14.0];
float lineSize = 0;
float lineNumber = 0;
NSArray *listOfFrameX = [NSArray arrayWithObjects:
[NSString stringWithFormat:#"%d",FIRST_LINE_Y],
[NSString stringWithFormat:#"%d",SECOND_LINE_Y],
[NSString stringWithFormat:#"%d",THIRD_LINE_Y],
nil];
for (int i = 0; i < [listOfNames count]; i++) {
CGSize expectedLabelSize = [[[listOfNames objectAtIndex:i] objectForKey:#"name"] sizeWithFont:buttonFont
constrainedToSize:maximumLabelSize
lineBreakMode:UILineBreakModeTailTruncation];
if ((lineSize + expectedLabelSize.width) > 260) {
lineNumber++;
lineSize = 0;
}
if (lineNumber > 2) {
viewNumber ++;
lineSize = 0;
lineNumber = 0;
}
CGRect newFrame = CGRectMake(lineSize,
[[listOfFrameX objectAtIndex:lineNumber] floatValue],
expectedLabelSize.width+30,
24);
CustomButton *myButton = [[CustomButton alloc] initWithFrame:newFrame
title:[[listOfNames objectAtIndex:i] objectForKey:#"name"]
tag:[[[listOfNames objectAtIndex:i] objectForKey:#"id"] intValue]];
myButton.buttonViewNumber = viewNumber;
[listOfButtons addObject:myButton];
if (viewNumber == 0) {
[self addSubview:myButton];
}
lineSize += expectedLabelSize.width + 40;
[myButton release];
}
}
this way it works:
- (void)viewDidLoad
{
[super viewDidLoad];
placeholders = [[NSArray arrayWithObjects:
something,something, something,something,nil] retain];
CGRect frame = CGRectMake(10, 247, 300, 84);
buttonsView = [[ButtonsView alloc] initWithFrame:frame bundle:placeholders];
[self.view addSubview:buttonsView];
and like this is doesnt work:
- (void)getCompanyNames:(id)result
{
NSArray *listOfCompanies = (NSArray *)result;
CGRect frame = CGRectMake(10, 247, 300, 84);
buttonsView = [[ButtonsView alloc] initWithFrame:frame bundle:listOfCompanies];
[self.view addSubview:buttonsView];
}
i need to add the "buttonsView" object to self.view after the -viewDidLoad
drawRect: isn't exactly the place you should be creating subviews (Buttons are subviews) for your view. This should either go into initWithFrame: or awakeFromNib, depending on your view creation method: programmatically or using a nib.
Can any one tell me why I am getting this error ?
[myClassName
tableView:numberOfRowsInSection:]:
unrecognized selector sent to instance
0x8ad5a90'
I know what does it means but in myClassName class I didn't use any uitableview!!!! I have a scrollview in this class not tableView so I could not find why I am getting this error.
EDITED :
- (void)viewDidLoad
{
imageIndex = 0;
int count =0;
int totalScrollRow = 0;
myScroll.contentSize = CGSizeMake(0, 397);
NSLog(#"%f",myScroll.contentSize.height);
volPhotoApp = (MyAppDelegate *) [[UIApplication sharedApplication] delegate];
volPhotoApp.photoGalleryIndex = 0 ;
eventRow = [volPhotoApp.volPhotoArray objectAtIndex:selectedIndex];
numberOfImages = [eventRow.photoArray count];
if (numberOfImages == 0)
{
UILabel *zeroLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 200)];
zeroLabel.text = #"No Images..";
[myScroll addSubview:zeroLabel];
return;
}
header.enabled =NO;
[header setTitle:eventRow.title forState:UIControlStateNormal];
CGRect contentRect = myScroll.bounds;
CGFloat boundX = contentRect.origin.x;
CGFloat boundY = contentRect.origin.y;
CGRect frame1 ;
for (int i=0, X=5 ; i < numberOfImages; i++, X+=80)
{
if (count == 4)
{
boundX = 5;
boundY += 70;
X = 0;
count = 0;
}
frame1 = CGRectMake(boundX+X ,boundY+5, 70, 65);
AsyncImageView *av1 = [[AsyncImageView alloc] initWithFrame:frame1];
[av1 loadImageFromURL:[NSURL URLWithString:[eventRow.photoArray objectAtIndex:volPhotoApp.photoGalleryIndex]]];
av1.backgroundColor = [UIColor clearColor];
volPhotoApp.photoGalleryIndex++;
UIButton *b1 = [[UIButton alloc] initWithFrame:frame1];
b1.backgroundColor = [UIColor clearColor];
[b1 setTitle:#"" forState:UIControlStateNormal];
b1.tag = volPhotoApp.photoGalleryIndex;
[b1 addTarget:self action:#selector(aMethod:) forControlEvents:UIControlEventTouchDown];
b1.enabled = YES;
count++;
[myScroll addSubview:av1];
[myScroll addSubview:b1];
totalScrollRow++;
if (volPhotoApp.photoGalleryIndex == numberOfImages)
{
volPhotoApp.photoGalleryIndex = 0 ;
break;
}
}
NSLog(#"%f",boundY);
NSLog(#"%d",totalScrollRow);
NSLog(#"%f",myScroll.contentSize.height);
if (boundY > myScroll.contentSize.height || totalScrollRow > 20)
{
myScroll.contentSize = CGSizeMake(0, boundY+75);
}
[super viewDidLoad];
}
Thanks..
Could you be inheriting from UITableViewController or acting as the delegate? Without code it's only guessing.
I have a UITable and when I click on a row I load a set of images.
I create the images with
UIImage *image = [UIImage imageWithData:data];
The problem is that ever time I click on the same row, the images are re-allocated into memory, like if no cache it is used and no memory is freed, so the allocated memory keep increasing. (I see this using the Inspector on both the device and the emulator)
I am releasing everything and also, with clang, everything looks fine.
The point is that after a while my app crashes.
Any suggestion or idea?
EDIT:
Here is the portion of code I think is generating the issue:
UIView *main = [[[UIView alloc] initWithFrame:rectScrollView] autorelease];
for (int i=0; i<[contentArray count]; i++) {
float targetWidth = rectScrollView.size.width;
float targetHeight = rectScrollView.size.height;
Link *tmp_link = [contentArray objectAtIndex:i];
AsyncImageView* asyncImage = nil;
if(tmp_link!=nil){
CGRect imageFrame = CGRectMake(targetWidth*i, 0, targetWidth, targetHeight);
//asyncImage = [[[AsyncImageView alloc] initWithFrame:imageFrame ] autorelease];
asyncImage = [[AsyncImageView alloc] initWithFrame:imageFrame ];
asyncImage.contentMode = UIViewContentModeScaleAspectFit;
NSURL* url = [NSURL URLWithString:[[IMG_SERVER_URL stringByAppendingString: tmp_link.url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
[asyncImage loadImageFromURL:url];
[self.scrollView addSubview:(UIImageView *)asyncImage];
[asyncImage release];
}
if ([tmp_link.caption length] > 0 && asyncImage!=nil) {
float marginTop = 25;
UILabel *caption = [[UILabel alloc] init];
caption.text = tmp_link.caption;
caption.textAlignment = UITextAlignmentCenter;
caption.textColor = [UIColor whiteColor];
caption.font = [UIFont systemFontOfSize:12];
caption.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.4];
CGRect captionFrame = CGRectMake((i * targetWidth), marginTop+10, targetWidth, 20.0f);
caption.frame = captionFrame;
[self.scrollView addSubview:caption];
[caption release];
}
//[asyncImage release];
}
[main addSubview:scrollView];
[scrollView release];
if (pageControlEnabledTop) {
rectPageControl = CGRectMake(0, 5, scrollWidth, 15);
}
else if (pageControlEnabledBottom) {
//rectPageControl = CGRectMake(0, (scrollHeight - 25), scrollWidth, 15);
rectPageControl = CGRectMake(0, (scrollHeight), scrollWidth, 15);
}
if (pageControlEnabledTop || pageControlEnabledBottom) {
//pageControl = [[[UIPageControl alloc] initWithFrame:rectPageControl] autorelease];
pageControl = [[UIPageControl alloc] initWithFrame:rectPageControl];
pageControl.numberOfPages = [contentArray count];
pageControl.currentPage = page;
[main addSubview:pageControl];
[pageControl release];
}
if (pageControlEnabledTop || pageControlEnabledBottom || rememberPosition) self.scrollView.delegate = self;
//if (margin) [margin release];
return (UIScrollView *)main;
And it is used like this:
reviewImagesImage = [[IGUIScrollViewImage alloc] init];
if([currentReview.linkScreenshots count]>0){
//reviewImages
reviewImages = [[UIView alloc] init];
//placing the images
CGRect frameImages = reviewImages.frame;
frameImages.origin.x = 10;
frameImages.origin.y = (infoView.frame.origin.y + infoView.frame.size.height + 10.0f);
frameImages.size.width = 300;
frameImages.size.height = 350.0f;
reviewImages.frame = frameImages;
reviewImages.backgroundColor = [UIColor clearColor];
[reviewImagesImage setContentArray:currentReview.linkScreenshots];
[reviewImagesImage setWidth:reviewImages.frame.size.width andHeight: reviewImages.frame.size.height];
[reviewImagesImage enablePageControlOnBottom];
[reviewImagesImage setBackGroudColor: [UIColor clearColor]];
UIScrollView *tmp_sv = [reviewImagesImage getWithPosition:0];
[reviewImages addSubview:tmp_sv];
[self.view addSubview:reviewImages];
[reviewImages release];
}
I have noticed that if I try to release reviewImagesImage my app crashes :/
Of course no cache is used because new UIImage will be created from the data every time. If memory usage significantly increased like you have said, it is most likely that it is our fault that unintentionally keep the reference retained somewhere.
Once you've set your image with imageWithData, save the image to the filepath in the app bundle.