I trying to figure out the best way to perform memory management on the following implementation:
I've a UIPopoverController which will be created upon viewDidLoad of the view and only be gone when viewDidUnload.
And Inside the UIPopoverController, I'm displaying a UITableView.
Here is my current implementation in .h:
UIPopoverController *aPopoverController;
#property (nonatomic, retain) UIPopoverController *aPopoverController;
In .m:
#synthesize *aPopoverController;
Inside a method in .m which is called when viewDidLoad:
UITableViewController *aTableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
UITableView *aTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 100, 800)];
aTableViewController.tableView = aTableView;
aTableView.delegate = self;
aTableView.dataSource = self;
aPopoverController = [[UIPopoverController alloc] initWithContentViewController:aTableViewController];
How should I release these objects when viewDidUnload?
Feel free to release both aTableView and aTableViewController right after this code.
To be more specific, UITableViewController retains the table view, so you don't need to keep it anymore, and UIPopoverController retains the content view controller, so you can release aTableViewController once you passed it to the popover controller.
In -viewDidUnload your popover controller is released, and it releases table view controller, which then releases the table view. Simple as that.
I'd put it like this:
UITableViewController *aTableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
UITableView *aTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 100, 800)];
aTableView.delegate = self;
aTableView.dataSource = self;
aTableViewController.tableView = aTableView;
[aTableView release];
aPopoverController = [[UIPopoverController alloc] initWithContentViewController:aTableViewController];
[aTableViewController release];
Related
I am creating an iphone application, where i have number of grid views in a main view controller class. So, i want when i select a grid cell from main view, should load a Reveal controller. The layout looks like
I have the following code in my Main View Controller.
-(void) gridView:(UzysGridView *)gridView didSelectCell:(UzysGridViewCell *)cell
atIndex:(NSUInteger)index
{
if (index == 0){
FrontViewController *frontViewController = [[FrontViewController alloc]
init];
RightViewController *rightViewController = [[RightViewController alloc] init];
UINavigationController *frontNavigationController = [[UINavigationController alloc]
initWithRootViewController:frontViewController];
SWRevealViewController *mainRevealController = [[SWRevealViewController alloc]
initWithRearViewController:nil
frontViewController:frontNavigationController];
mainRevealController.delegate = self;
self.revealController.rightViewController = rightViewController;
self.revealController = mainRevealController;
[self.navigationController pushViewController:self.revealController animated:YES];
}
here in main view controller .h file,
#property (strong, nonatomic) SWRevealViewController *revealController;
Also i have declare SWRevealViewControllerDelegate. Problem is that this self.revealController doesn't load/show. I have tried with App Delegate also, but nothing works.
thanks.
I solved it: Use the below code..
-(void) gridView:(UzysGridView *)gridView didSelectCell:(UzysGridViewCell *)cell
atIndex:(NSUInteger)index {
if (index == 0){
FrontViewController *frontViewController = [[FrontViewController alloc]
init];
myNavigationController = [[UINavigationController alloc]
initWithRootViewController:frontViewController];
SWRevealViewController *revealController = [[SWRevealViewController alloc]
initWithRearViewController:nil frontViewController:myNavigationController];
revealController.delegate = self;
RightViewController *rightViewController =
[[RightViewController alloc] init];
rightViewController.view.backgroundColor = [UIColor greenColor];
revealController.rightViewController = rightViewController;
self.viewController1=revealController;
[self presentViewController:self.viewController1 animated:YES completion:nil];
}
}
And in Class.h file
#property(nonatomic, strong) UINavigationController *myNavigationController;
#property(nonatomic, strong) SWRevealViewController *viewController1;
I have an application for which I use TabBar template. In one of viewcontrollers I want to add a uinavigationcontroller. I declare it in the .h file;
#import <UIKit/UIKit.h>
#import "AnotherViewController.h"
#interface SecondViewController : UIViewController <UINavigationControllerDelegate> {
UIButton *UIButton *gotoAnotherView;;
AnotherViewController *anotherView;
UINavigationController *navigationController;
}
#property(nonatomic,retain) UIButton *UIButton *gotoAnotherView;;
#property(nonatomic,retain) AnotherViewController *anotherView;
#property(nonatomic,retain) UINavigationController *navigationController;
-(void)buttonPressed:(id)sender;
#end
And here's my .m file
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize navigationController, anotherView, gotoAnotherView;
-(void)buttonPressed:(id)sender {
anotherView = [[AnotherViewController alloc]init];
[navigationController pushViewController:anotherView animated:YES];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
navigationController = [[UINavigationController alloc ]initWithRootViewController:self];
[navigationController.navigationBar setFrame:CGRectMake(0, 0, 320, 44)];
[self.view addSubview:navigationController.navigationBar];
gotoAnotherView = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 40, 40)]; //kategoributonlari
UIImage *image = [UIImage imageNamed:#"1.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(110, 5, 100, 20);
[self.view addSubview:imageView];
[kategori1 setBackgroundImage:image forState:UIControlStateNormal];
[kategori1 addTarget:self
action:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:kategori1];
[super viewDidLoad];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (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
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
However I can see from the navigation bar that the navigationcontroller goes one level deeper(back button appears) but the main view remains the same with my gotoAnotherView button.
I think that I might not make the navigationcontroller control the whole view.
Instead of trying to do this in code, edit the XIB for your main window (with the UITabBarController). Drag out a UINavigationController from the Library onto the tab bar. This will create a new bar item for you, with a UINavigationController. Select the UIViewController nested in the new UINavigationController, and on the Identity tab set the Class to your view controller, and on the Attributes tab specify the name of the nib file to load.
You don't need to use IB. You can setup everything in code. First create your view controllers tab1ViewController, tab2ViewController, etc. then create the navigation controller with the root view controllers of tab1ViewController etc. and then add these controllers to the tab bar controller.
Here is a sample:
UINavigationController *tab1NavigationController = [[UINavigationController alloc] initWithRootViewController:tab1ViewController];
UINavigationController *tab2NavigationController = [[UINavigationController alloc] initWithRootViewController:tab2ViewController];
UITabBarController rootViewController = [[UITabBarController alloc] init];
rootViewController.viewControllers = [NSArray arrayWithObjects:tab1NavigationController, tab2NavigationController, nil];
[tab1NavigationController release];
[tab2NavigationController release];
I wanted to double check that I was doing correct memory management. Is this correct? Do I have the correct amount of releases.
In my .h file:
UITableView *_sortOrderTableView;
#property (nonatomic, retain) UITableView *SortOrderTableView;
In my .m file:
In dealloc
[_sortOrderTableView release];
My code that presents the popover is this:
- (IBAction)sortButtonOrderPressed:(id)sender {
UIViewController *sortOrderController = [[UIViewController alloc] init];
self.SortOrderTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
self.SortOrderTableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"App_Background.png"]];
self.SortOrderTableView.bounces = NO;
self.SortOrderTableView.scrollEnabled = NO;
sortOrderController.view = self.SortOrderTableView;
sortOrderController.contentSizeForViewInPopover = CGSizeMake(200, 100);
self.SortOrderTableView.delegate = self;
self.SortOrderTableView.dataSource = self;
self.SortPopover = [[UIPopoverController alloc] initWithContentViewController:sortOrderController];
[self.SortPopover presentPopoverFromRect:_sortButtonOrder.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[self.SortOrderTableView release];
[sortOrderController release];
}
Remove [self.SortOrderTableView release];, it should be [_sortOrderTableView release]; or self.SortOrderTableView = nilanyway, but you're already calling that in your dealloc method, so there is no need to release it here. If you want to release it though, use self.SortOrderTableView = nil.
Apart from that you will also have to release your SortPopover's instance variable in your dealloc method.
I'm trying to base part of my app off of Apple's Image Zooming example, to get zooming, scrolling, and orientation of images that are saved to the app's sandbox.
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html
I have it sort of working now, except that when the ScrollView loads, it's blank. The code looks something like this:
#interface PhotoViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *imageScrollView;
UIImageView *imageView;
}
#property (nonatomic, retain) IBOutlet UIScrollView *imageScrollView;
#property (nonatomic, retain) UIImageView *imageView;
#end
#implementation PhotoViewController
#synthesize imageView, imageScrollView;
- (void)viewDidLoad {
[super viewDidLoad];
imageScrollView.bouncesZoom = YES;
imageScrollView.delegate = self;
imageScrollView.clipsToBounds = YES;
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.jpg"]];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
imageView.userInteractionEnabled = YES;
[imageScrollView addSubview:imageView];
imageScrollView.contentSize = [imageView frame].size;
}
The xib has a Photo View Controller->Scroll View->View structure. I have a feeling this is where the problem is. I tried to hook up all the outlets identically to the example, but under Referencing Outlets the example has a viewController hooked up to the ImageZoomingAppDelegate. Since my PhotoViewController is a subview, there's not a place to hook up the viewController like that.
Here's how I bring up the PhotoViewController:
(IBAction) photoButtonPressed: (id) sender {
viewController = [[PhotoViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
I know I must be just "this close" to having it all hooked up right, but I don't understand the relationship of the xib to the code well enough to know how to debug it. I'm not even sure if I know enough to ask the right questions.
Try changing viewController = [[PhotoViewController alloc] init]; to
viewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
(of course change the text string to whatever you called your xib file).
I have a weird problem.
I'm subclassing UIViewController and adding a tableView property in which I load a UITableView.
Now I'm adding this UITableView to the parent's subviews.
Works fine but I get TWO TableViews. One standard styled TableView and one the way I wanted it to be on top of the standard one. Both contain the correct data though.
#interface RootViewController : UIViewController <ABPersonViewControllerDelegate, UITableViewDelegate, UITableViewDataSource> {
UITableView *tableView;
ToolbarController *toolbar;
...
}
#property(nonatomic, retain) UITableView *tableView;
#property(nonatomic, retain) ToolbarController *toolbar;
...
#end
#implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
CGRect mainViewBounds = self.parentViewController.view.bounds;
CGFloat toolbarHeight = 44;
toolbar = [[ToolbarController alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(mainViewBounds), toolbarHeight) parentView:self];
tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, toolbarHeight, CGRectGetWidth(mainViewBounds), CGRectGetHeight(mainViewBounds) - toolbarHeight) style:UITableViewStylePlain];
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
tableView.rowHeight = 60.0;
[tableView tableView].delegate = self;
[tableView tableView].dataSource = self;
tableView.backgroundColor = [UIColor clearColor];
[self.parentViewController.view addSubview:tableView];
[self.parentViewController.view addSubview:toolbar];
}
#end
------UPDATED------
I just wrongly pasted one part
[tableView tableView].delegate = self;
[tableView tableView].dataSource = self;
is actually in code
tableView.delegate = self;
tableView.dataSource = self;
-------UPDATE 2--------
If I don't create my own UITableView by
tableView = [[UITableView alloc] ...]
then there is one automatically set for me.
This would be fine for me... I don't need to init one, but I can't change the frame on the standard one.
tableView.frame = CGRectMake(0, toolbarHeight, CGRectGetWidth(mainViewBounds), CGRectGetHeight(mainViewBounds) - toolbarHeight);
Setting frame has no effect whatsoever...
i Had the same issue you probably be converting the UITableViewController to UIViewController and Your RootViewController might have the uitableview.
Make the Property of _tableview in your RootviewController with IBOutlet. And link it with the tableview in your XIB .
Don't alloc _tableview in RootviewController and Don't addsubview it .
Instead of this,
[tableView tableView].delegate = self;
[tableView tableView].dataSource = self;
Have you tried just using:
tableView.delegate = self;
tableView.dataSource = self;
I don't know why it would be that, but it's the only thing that's standing out. Also make sure you haven't got another UITableView set up in IB.
It might also have something to do with toolbarController.
I'm assuming it's a custom class, so make sure you're not creating a UITableView in that.
I ran into same issue...
Instead of adding tableview to the view controller directly ([self.parentViewController.view addSubview:tableView];), use following way..
UIView *totalView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
[totalView addSubview:tableView];
self.view=totalView;
Hope this fixes it (for #kris too!)