UIImageView drifting on viewDidLoad - iphone

I am programmatically adding a UIImageView and a UILabel to multiple screens in a program I'm working on. As such, I've written a UIViewController that contains the code to load up the UIImageView and UILabel in viewDidLoad, along with a timer to update the contents. I use this view controller as a superclass for any views that need the UIImageView and UILabel.
For the most part it works fine, but when transitioning from specific screens the pair seem to start with a frame of (0,0,0,0) and slowly animate to the frame I've defined. I have no idea what the issue is or even where to look. Any pointers here would be great.
Here is the code I'm using as my superclass.
FoundationViewController.h
#import
#interface FoundationViewController : UIViewController {
IBOutlet UIImageView *activeInventoryImage;
IBOutlet UILabel *activeInventoryLabel;
NSTimer *inventoryStatusTimer;
}
#property (nonatomic, retain) IBOutlet UIImageView *activeInventoryImage;
#property (nonatomic, retain) IBOutlet UILabel *activeInventoryLabel;
- (void) advanceToView:(id)nextView;
- (void) inventoryStatus;
- (BOOL) inventoryActive:(NSDate*)inventoryExpire withImage:(NSString*)imageName;
#end
FoundationViewController.m
#import "FoundationViewController.h"
#import "GameData.h"
#import "Globals.h"
#implementation FoundationViewController
#synthesize activeInventoryImage;
#synthesize activeInventoryLabel;
- (void) viewDidLoad{
// initialize the active inventory icon and label
activeInventoryImage = [[UIImageView alloc] init];
activeInventoryLabel = [[UILabel alloc] init];
// clear
activeInventoryImage.image = [UIImage imageNamed:#""];
activeInventoryLabel.text = #"";
// set the center points
activeInventoryImage.frame = CGRectMake(258, 7, 20, 20);
activeInventoryLabel.frame = CGRectMake(280, 6, 30, 20);
// set label parameters
activeInventoryLabel.backgroundColor = [UIColor clearColor];
activeInventoryLabel.font = [UIFont fontWithName:#"Helvetica" size:11.0f];
activeInventoryLabel.textColor = [UIColor colorWithRed:0.2 green:0.4 blue:0.6 alpha:1];
// add to view
[self.view addSubview:activeInventoryImage];
[self.view addSubview:activeInventoryLabel];
// start the timer if there is any active inventory
if(
[self inventoryActive:[GameData sharedGameData].player.inventory.aExpire withImage:#"a.png"] ||
[self inventoryActive:[GameData sharedGameData].player.inventory.bExpire withImage:#"b.png"] ||
[self inventoryActive:[GameData sharedGameData].player.inventory.cExpire withImage:#"c.png"]
)
inventoryStatusTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(inventoryStatus) userInfo:nil repeats:YES];
[super viewDidLoad];
}
- (BOOL) inventoryActive:(NSDate*)inventoryExpire withImage:(NSString*)imageName{
NSTimeInterval expireSeconds;
NSDateFormatter *formatter;
BOOL runTimer = FALSE;
// expire
expireSeconds = [inventoryExpire timeIntervalSinceNow];
if(expireSeconds > 0){
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"mm:ss"];
NSDate *expireTime = [NSDate dateWithTimeIntervalSince1970:expireSeconds];
activeInventoryImage.image = [UIImage imageNamed:imageName];
activeInventoryLabel.text = [formatter stringFromDate:expireTime];
[formatter release];
runTimer = TRUE;
}
return runTimer;
}
- (void) inventoryStatus{
// if there is no active inventory kill the timer
if(
![self inventoryActive:[GameData sharedGameData].player.inventory.aExpire withImage:#"a.png"] &&
![self inventoryActive:[GameData sharedGameData].player.inventory.bExpire withImage:#"b.png"] &&
![self inventoryActive:[GameData sharedGameData].player.inventory.cExpire withImage:#"c.png"]
){
activeInventoryImage.image = [UIImage imageNamed:#""];
activeInventoryLabel.text = #"";
if(inventoryStatusTimer != nil)
[inventoryStatusTimer invalidate];
}
}
- (void) advanceToView:(id)nextView{
if([nextView isKindOfClass:[UIView class]]){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.7];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.view cache:YES];
[self.view addSubview:nextView];
[UIView commitAnimations];
}
else
NSLog(#" Error Loading View: %#",nextView);
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[activeInventoryImage removeFromSuperview];
[activeInventoryImage release];
[activeInventoryLabel release];
[super dealloc];
}
#end

Put a break point in advanceToView as this seems to be your only animation code. Everytime it gets called, look at the call stack in the debugger. From here, you can see what is calling this code when they are not supposed to be.

After some experimenting I've discovered using initWithFrame corrects the drifting problem.
activeInventoryImage = [[UIImageView alloc] initWithFrame:CGRectMake(258, 7, 20, 20)];
activeInventoryLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 6, 30, 20)];
I still have no idea what the root cause of the issue is. If anyone could tell me what's going on here I would love to know for future reference.

Related

iphone - getting UIImageView to repeatedly move

Background: I am using xcode 3.1.4 and iphone simulator 3.1 (I know it's outdated and please dont comment about that).
Goal: I am trying to get a UIImageView that is created once the view loads to continuously move down. Creating the UIImageView works fine, but the move function does not work. Nothing happens. I use an NSTimer. Here is my code in the view controller.m file:
-(void)viewDidLoad{
UIImageView *six = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Meteor.png"]];
CGRect rectSix = CGRectMake(arc4random() % (250), arc4random() % (1), 35, 35);
[six setFrame:rectSix];
[self.view addSubview:six];
[self moveMeteor:six];
[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:#selector(moveMeteor:) userInfo:six repeats:YES];
}
-(void)moveMeteor:(UIImageView *)t{
t.center=CGPointMake(t.center.x, t.center.y + 1);
}
And of course, I declared my moveMeteor function in the view controller.h file. By typing in:
-(void)moveMeteor:(UIImageView *)t;
Any ideas of what the problem is and a solution to it?
Or you could do something like this, which takes advantage of UIView's animateWithDuration and should look much better. No timer required.
// in your interface declaration...
#property (nonatomic, assign) BOOL meteorShouldAnimate;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
// in your implementation...
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.meteorShouldAnimate = YES;
[self moveMeteorWithAnimationOptions:UIViewAnimationOptionCurveEaseIn]; // ease in to the animation initially
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.meteorShouldAnimate = NO;
}
- (void)moveMeteorWithAnimationOptions: (UIViewAnimationOptions) options {
__weak MyViewController * weakSelf = self;
if (self.meteorShouldAnimate) {
[UIView animateWithDuration:0.2 delay:0.0 options:options animations:^{
self.imageView.transform = CGAffineTransformMakeTranslation(20.0, 20.0); // or whatever x and y values you choose
} completion:^(BOOL finished) {
MyViewController * strongSelf = weakSelf; // in case our view controller is destroyed before our completion handler is called
if (strongSelf) {
UIViewAnimationOptions nextOptions = strongSelf.meteorShouldAnimate ? UIViewAnimationOptionCurveLinear : UIViewAnimationOptionCurveEaseOut; // linear if we're continuing to animate, ease out if we're stopping
[strongSelf moveMeteorWithAnimationOptions:nextOptions];
}
}];
}
}
Your method is actually not getting the right parameter, you get NSTimer as a parameter. so instead
-(void)moveMeteor:(UIImageView *)t
the method should be like this
-(void)moveMeteor:(NSTimer *)timer
and you can't treat NSTimer as an UIImageView. :)
*Edit
I would suggest you to do something like
-(void)viewDidLoad{
UIImageView *six = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Meteor.png"]];
CGRect rectSix = CGRectMake(arc4random() % (250), arc4random() % (250), 35, 35);
[six setFrame:rectSix];
[self.view addSubview:six];
[self moveMeteor:six];
[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:#selector(moveMeteor:) userInfo:six repeats:YES];
}
and update your method to this
- (void)moveMeteor:(NSTimer *)timer {
UIImageView *six = timer.userInfo;
six.center=CGPointMake(six.center.x, six.center.y + 1);
}
just for information, I am passing the UIImageView in the dictionary as userInfo.

Creating a Label via a method in a class

I am slowly developing a custom button (while learning how to implement classes etc).
I have a ViewController, which imports a SuperButton.h (UIControl) and then creates an instance of the SuperButton. (This works, as proved by a NSLog.)
But I cannot get the method in SuperButton to display a Label.
I think this might have something to with the '.center' value or the 'addSubview' command?
I would really appreciate your help. Thanks.
Here is my SuperButton.m code:
#import "SuperButton.h"
#implementation SuperButton
#synthesize firstTitle;
#synthesize myLabel;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void) shoutName{
NSLog(#"My name is %#", firstTitle);
self.backgroundColor = [UIColor blueColor];
CGRect labelFrame = CGRectMake(0.0f, 0.0f, 100.0f, 50.0f);
self.myLabel = [[UILabel alloc] initWithFrame:labelFrame];
self.myLabel.text = #"Come on, don't be shy.";
self.myLabel.font = [UIFont italicSystemFontOfSize:14.0f];
self.myLabel.textColor = [UIColor grayColor];
self.myLabel.center = self.center;
[self addSubview:self.myLabel];
}
Here is the code in my ViewController:
- (void) makeButton{
SuperButton *button1 = [[SuperButton alloc] init];
button1.firstTitle = #"Mr. Ploppy";
[button1 shoutName];
}
(EDIT:) Just in case, here's the SuperButton.h code:
#import <UIKit/UIKit.h>
#interface SuperButton : UIControl
#property (nonatomic, strong) NSString *firstTitle;
#property (nonatomic, strong) UILabel *myLabel;
- (void) shoutName;
#end
I found an answer elsewhere.
I needed to addSubview the 'button'. My working code now looks like this:
- (void) makeButton{
SuperButton *button1 = [[SuperButton alloc] init];
button1.firstTitle = #"Mr. Ploppy";
[button1 shoutName];
[self.view addSubview:button1.myLabel];
[self.view sendSubviewToBack:button1.myLabel];
}
You are initializing your button not with initWithFrame: method, but with simple init. This makes the button of CGRectZero size. Change this line:
SuperButton *button1 = [[SuperButton alloc] init];
to this:
SuperButton *button1 = [[SuperButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 50.0f)];
or add a call to setFrame: after initializing your button.

How do I choose between multiple UILabels by touch?

I have 2 UIButtons setup(+/-) when tapped, the number changes by one within a UILabel. What do I need to do to have multiple UILabels and when one is touched I can change its current value with the UIButton(+/-)?
Have a variable that you use as the active label, then add a gesture recognizer to both the UIlabels to capture taps:
label.userInteractionEnabled = YES;
UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecieved:)];
[label addGestureRecognizer:tap];
[tap release];
//repeat for each additional label
Then in your tapReceived method, swap out the active label
-(void) tapRecieved:(UITapGestureRecognizer *)tap{
currentLabel = (UILabel *) tap.view;
}
Then in the method that you capture clicks to the +/- button, write to currentLabel
Edit: A quick and dirty implementation of your problem. In interface builder I made 2 labels and a button and hooked them up. When you tap a label, it becomes the currentLabel and when you tap the button, whichever label you chose is incremented by 1. Hope it helps.
.h
#import <UIKit/UIKit.h>
#interface junkViewController : UIViewController {
UILabel *label;
UILabel *label2;
UILabel *currentLabel;
int label1Value;
int label2Value;
}
#property (nonatomic, retain) IBOutlet UILabel *label;
#property (nonatomic, retain) IBOutlet UILabel *label2;
- (IBAction)buttonTap:(id)sender;
#end
.m
#import "junkViewController.h"
#implementation junkViewController
#synthesize label;
#synthesize label2;
- (void)dealloc
{
[label release];
[label2 release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
-(void) tapRecieved:(UITapGestureRecognizer *)tap{
currentLabel = (UILabel *)tap.view;
NSLog(#"tap %#",tap.view);
}
-(void) viewDidLoad{
currentLabel = label;
label.text = [NSString stringWithFormat:#"%d",label1Value];
label2.text = [NSString stringWithFormat:#"%d",label2Value];
label.userInteractionEnabled = YES;
UIGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecieved:)];
[label addGestureRecognizer:tap];
[tap release];
tap = nil;
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecieved:)];
label2.userInteractionEnabled = YES;
[label2 addGestureRecognizer:tap];
[tap release];
}
- (void)viewDidUnload
{
[self setLabel:nil];
[self setLabel2:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)buttonTap:(id)sender {
int value = [currentLabel.text intValue] + 1;
currentLabel.text = [NSString stringWithFormat:#"%d",value];
}
#end
I had to do something similar recently for a dynamically created menu in my app. This worked well:
In the menu creation method:
#define NAV_WIDTH 220
#define NAV_HEIGHT 220
#define NAV_TOP_HEIGHT 16
#define NAV_ITEM_HEIGHT 30
#define NAV_BOTTOM_HEIGHT 24
#define NAV_LABEL_MARGIN 20
[navPage setFrame: CGRectMake(navLeftCorner, navTopCorner, NAV_WIDTH, NAV_HEIGHT)];
NSArray *menuTitles = [[NSArray alloc] initWithObjects: #"One", #"Two", #"Three", #"Four", nil];
int tag = 1;
double labelTop = NAV_TOP_HEIGHT;
for (NSString *title in menuTitles) {
UILabel *itemLabel = [[UILabel alloc] initWithFrame: CGRectMake(NAV_LABEL_MARGIN, labelTop, NAV_WIDTH - (NAV_LABEL_MARGIN * 2), NAV_ITEM_HEIGHT)];
[itemLabel setUserInteractionEnabled: YES];
UITapGestureRecognizer *menuTap = [[UITapGestureRecognizer alloc] initWithTarget: self action: #selector(menuTapped:)];
[itemLabel addGestureRecognizer: menuTap];
[itemLabel setText: title];
[itemLabel setTag: tag];
[navPage addSubview: itemLabel];
labelTop += NAV_ITEM_HEIGHT;
tag++;
}
. . . which calls this when tapped:
- (void) menuTapped: (UITapGestureRecognizer *)tap
{
UILabel *currentLabel = (UILabel *) tap.view;
int index = (currentLabel.tag - 1);
/* Do stuff based on the tag index */
}
NOTE: This is the ARC-compliant way; add [itemLabel release] after adding to the subview if you're not using ARC.

Xcode/iPhone: First Windows-Based Application - Why isn't anything showing up in the TabBarController views

Is there something that I need to remember when using the windows-based template? Because I'm unclear as to why the tabs are showing up but nothing in the views are showing up.
Could you help? Because I've been searching through previous questions for a few hours now and I still haven't found anything to clear this up.
AnotherMadeUpAppDelegate.h
#import <UIKit/UIKit.h>
#import "AnotherMadeUpViewController.h"
#interface AnotherMadeUpAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
AnotherMadeUpAppDelegate.m
#import "AnotherMadeUpAppDelegate.h"
#implementation AnotherMadeUpAppDelegate
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIViewController *vc1 = [[UIViewController alloc] init];
UIViewController *vc2 = [[UIViewController alloc] init];
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] init];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:vc1, vc2, vc3, nil];
[vc1 release];
[vc2 release];
[vc3 release];
[self.window addSubview:tbc.view];
[self.window makeKeyAndVisible];
return YES;
}
...
#end
AnotherMadeUpViewController.h
#import <UIKit/UIKit.h>
#interface AnotherMadeUpViewController : UIViewController<UIScrollViewDelegate>
{
IBOutlet UIPageControl *pageControl;
IBOutlet UIScrollView *scroller;
IBOutlet UILabel *label;
}
#property (nonatomic,retain)IBOutlet UIPageControl *pageControl;
#property (nonatomic,retain)IBOutlet UIScrollView *scroller;
#property (nonatomic,retain)IBOutlet UILabel *label;
-(IBAction)clickPageControl:(id)sender;
#end
AnotherMadeUpViewController.m
#import "AnotherMadeUpViewController.h"
#implementation AnotherMadeUpViewController
#synthesize pageControl,scroller,label;
-(IBAction)clickPageControl:(id)sender
{
int page=pageControl.currentPage;
CGRect frame=scroller.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scroller scrollRectToVisible:frame animated:YES];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int page = scrollView.contentOffset.x/scrollView.frame.size.width;
pageControl.currentPage=page;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
[label release];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
scroller.pagingEnabled=YES;
CGFloat labelOriginX = label.frame.origin.x;
CGFloat labelOriginY = label.frame.origin.y;
CGFloat scrollWidth = 0;
int pageNumber = 0;
for (int i=0; i<9; i++)
{
CGRect rect = label.frame;
rect.size.height = label.frame.size.height;
rect.size.width = label.frame.size.width;
rect.origin.x = labelOriginX + scrollWidth;
rect.origin.y = labelOriginY;
label.frame = rect;
label.text = [NSString stringWithFormat:#"%d", pageNumber];
label.textColor = [UIColor redColor];
[scroller addSubview:label];
pageNumber++;
scrollWidth += scroller.frame.size.width;
}
scroller.delegate=self;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
pageControl.numberOfPages=9;
pageControl.currentPage=0;
scroller.contentSize=CGSizeMake(pageControl.numberOfPages*self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:scroller];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[label release];
self.label = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Dissecting your viewDidLoad –
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
You seem to be creating a new scroll view instance here but you have declared it as an outlet. If you don't have an outlet then remove the IBOutlet tag for scroller. If you do have one and want to use it then remove the above line. A shorter way of doing it would be,
scroller = [[UIScrollView alloc] initWithFrame:self.view.bounds];
Another thing is that you are creating 10 labels but assigning no frame. To show one of them each in different page,
int pageNumber = 0;
for (int i = 0; i < 10; i++)
{
UILabel *label = [[UILabel alloc] init];
[label sizeToFit];
label.center = CGPointMake (((2 * i + 1) * self.view.frame.size.width) / 2, self.view.frame.size.height / 2);
label.text = [NSString stringWithFormat:#"%d", pageNumber];
[scroller addSubview:label];
[label release];
pageNumber++;
}
and later set the contentSize to show 10 pages,
scroller.contentSize = CGSizeMake(10 * self.view.frame.size.width, self.view.frame.size.height);
The problem is with this line
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] init];
You need to change it to
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] initWithNibName:#"AnotherMadeUpViewController" bundle:nil];
Then your .xib will get loaded and your outlets will be connected.
And don't forget to connect your outlets to File's owner in IB.

UIImageView Allocating Memory Every Time Image Changed - How To Release?

I'm trying to create an application that allows users to go through a set of images like a magazine. I've got one UIView class on top of the AppDelegate and on swipe to the left/right I'm either going forward or backward a page. My problem is that when I swipe and change the image source the program keeps allocating more memory, and I'm not certain where/how to release the previously allocated memory. I've looked in to the difference between imageNamed and imageWithContentsOfFile and I believe I'm using those correctly so I'm stumped. Any help would be much appreciated!
AppDelegate.h
#interface AppDelegate : NSObject {
UIWindow *window;
MagazineWebViewController *webViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MagazineWebViewController *webViewController;
- (void)goToA:(NSNumber *)page;
#end
AppDelegate.m
#implementation AppDelegate
#synthesize window, webViewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
webViewController = [[MagazineWebViewController alloc] init];
NSNumber *page = [NSNumber numberWithInt:1];
[webViewController setPage:page];
[window addSubview:webViewController.view];
[window makeKeyAndVisible];
}
- (void)goToA:(NSNumber *)page {
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#", page] ofType:#"png"]];
webViewController.imageView.image = image;
[image release];
[webViewController setPage:page];
}
- (void)dealloc {
[webViewController release];
webViewController = nil;
[window release];
[super dealloc];
}
#end
MagazineWebViewController.h
#interface MagazineWebViewController : UIViewController {
UIImageView *imageView;
NSNumber *page;
}
#property (nonatomic, assign)NSNumber *page;
#property (nonatomic, retain)UIImageView *imageView;
- (void)swipeLeft;
- (void)swipeRight;
- (void)tableOfContents;
#end
MagazineWebViewController.m
#implementation MagazineWebViewController
#synthesize page, tocController, imageView;
- (id)init {
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 768, 60)];
navBar.tintColor = [UIColor blackColor];
UIBarButtonItem *contents = [[UIBarButtonItem alloc] initWithTitle:#"Table of Contents" style:UIBarButtonItemStylePlain target:self action:#selector(tableOfContents)];
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:#"Title"];
item.leftBarButtonItem = contents;
item.hidesBackButton = YES;
[navBar pushNavigationItem:item animated:NO];
[contents release];
[item release];
[self.view addSubview:navBar];
[navBar release];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 40, 768, 984)];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"1" ofType:#"png"]];
self.imageView.image = image;
[image release];
self.imageView.contentMode = UIViewContentModeScaleToFill;
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeft];
[swipeLeft release];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRight)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeRight];
[swipeRight release];
[self.view addSubview:self.imageView];
[self.imageView release];
return self;
}
- (void)swipeLeft {
int pageNum = [page intValue];
if (pageNum < 115) {
pageNum++;
UIViewAnimationTransition trans = UIViewAnimationTransitionCurlUp;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:trans forView:self.view.window cache:YES];
BaseballMagazine2011AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate goToA:[NSNumber numberWithInt:pageNum]];
[UIView commitAnimations];
}
}
- (void)swipeRight {
int pageNum = [page intValue];
if (pageNum > 1) {
pageNum--;
UIViewAnimationTransition trans = UIViewAnimationTransitionCurlDown;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:trans forView:self.view.window cache:YES];
BaseballMagazine2011AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate goToA:[NSNumber numberWithInt:pageNum]];
[UIView commitAnimations];
}
}
- (void)tableOfContents {
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[imageView release];
imageView = nil;
[page release];
page = nil;
[tocController release];
tocController = nil;
[super viewDidUnload];
}
- (void)dealloc {
[imageView release];
imageView = nil;
[page release];
page = nil;
[super dealloc];
}
#end
In your AppDelegate.m, Try prefacing each reference to webViewController with 'self.'. For example:
self.webViewController = [[MagazineWebViewController alloc] init];
By not referencing the property with self, you are bypassing the properties auto generated setters and getters. And since you set this property to retain, this would bypasses some memory handling logic. I'm pretty sure that is your issue... Hope this helps!
I think it's because you alloc every time an UIImage (like said in the comments).
Did you try not doing allocations ?
self.imageView.image = [ UIImage imageNamed:#"1.png" ];
I think you won't have any problem with this.
But it's difficult to say where come from the leak without all your program ^^
Maybe a retain property or something like that.