tabBarController set to nil when changing view but always in the window - iphone

I'm currently using a tableview inside a navigation controller, inside a tab bar controller. When i'm on the detail view of the table view, i want to "swipe" between Detail view, so i have implemented a UISwipeGesture with UIViewAnimations to swipe right/left.
Everything is working, but I have a little problem... When i'm on a Detail View loaded from the table view, the self.tabBarController element is here, i have my tab bar so i can add an actionsheet on it. But when i swipe, the self.tabBarController is nil now... I don't know why... Maybe because of the navigation Controller ?
Here is my code :
- (id) init
{
if (self = [super init]) {
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
UIScrollView *scrollView=[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, fullScreenRect.size.width, 367.)];
scrollView.contentSize=CGSizeMake(320,100);
scrollView.delegate = self;
self.view=scrollView;
self.myView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 367.)];
self.ButtonSizeM.tag = 0;
self.ButtonSizeP.tag = 0;
self.ContentIV = [[UIImageView alloc] init];
}
return self;
}
- (void) handleSwipeLeft {
if (!((self.ancient.tableView.indexPathForSelectedRow.section == ([self.ancient numberOfSectionsInTableView:self.ancient.tableView] - 1)) && (self.ancient.tableView.indexPathForSelectedRow.row == [self.ancient tableView:self.ancient.tableView numberOfRowsInSection:(self.ancient.tableView.indexPathForSelectedRow.section)]-1)))
{
NSIndexPath *whereToGo;
if (self.ancient.tableView.indexPathForSelectedRow.row == [self.ancient tableView:self.ancient.tableView numberOfRowsInSection:(self.ancient.tableView.indexPathForSelectedRow.section)]-1) {
whereToGo = [NSIndexPath indexPathForRow:0 inSection:(self.ancient.tableView.indexPathForSelectedRow.section)+1];
}
else {
whereToGo = [NSIndexPath indexPathForRow:(self.ancient.tableView.indexPathForSelectedRow.row)+1 inSection:self.ancient.tableView.indexPathForSelectedRow.section];
}
CCFASimpleDetail *nextView = [[CCFASimpleDetail alloc] init];
nextView = [self.ancient tableView:self.ancient.tableView prepareViewForIndexPath:whereToGo];
[nextView performSelectorOnMainThread:#selector(affichageEnPlace) withObject:nil waitUntilDone:YES];
float width = self.myView.frame.size.width;
float height = self.myView.frame.size.height;
[nextView.view setFrame:CGRectMake(width, 0.0, width, height)];
[self.view addSubview:nextView.view];
[UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
[nextView.view setFrame:self.view.frame];
[self.myView setFrame:CGRectMake(-width, 0.0, width, height)];
} completion:^(BOOL finished) {
[self.myView removeFromSuperview];
[self.ancient.tableView selectRowAtIndexPath:whereToGo animated:NO scrollPosition:UITableViewScrollPositionTop];
}
];
}
}
I you could help me to find my tab bar after swiping :) ?

When you add the view here:
[self.view addSubview:nextView.view];
the UINavigation controller does not know about it, and does not set the navigationBar nad tabBar properties for you.
What you can do is have the view get its superview (which will be self.view), then ask that view for the tabBarController and tabBar from that.

I just solved my problem by adding
[self.ancient.navigationController popViewControllerAnimated:NO];
[self.ancient.navigationController pushViewController:nextView animated:NO];
on the completion block !

Related

Handle UIButton in Child View Controller of Container View Controller

I am working on creating custom Container ViewController class and am able to create 5 sub viewcontrollers and able to move from one child view controller to other child using the following API:
transitionFromViewController:fromViewController
toViewController:toViewController
duration:1.0
options:0
animations:^{
}
completion:^(BOOL finished) {
}];
Child view controllers are occupying part of Parent View Controller. Each time when user swipe I am making previous controller goes off and present controller comes on displayable area.
Now I have buttons on child viewcontrollers and when i click on them I am not getting events or trigger to the Action method of Child View Controller. But Parent View Controller is getting callbacks for its buttons even currently childview is getting displayed. Adding the code snippet below (though it is little bigger, this will help you to analyze if I am doing any mistake).
Parent ViewController:
- (void) handleSwipeGestureLeft:(UISwipeGestureRecognizer *)gesture
{
if (showPopupValue) {
return;
}
NSInteger index = [arrayOfChildVCs indexOfObject:selectedViewController];
index = MIN(index+1, [arrayOfChildVCs count]-1);
UIViewController *newSubViewController = [arrayOfChildVCs objectAtIndex:index];
endFrame.origin.x = -1024;
startOfNewVCFrame.origin.x = 1024;
[self transitionFromViewController:selectedViewController toViewController:newSubViewController];
selectedViewController = newSubViewController;
}
- (void) handleSwipeGestureRight:(UISwipeGestureRecognizer *)gesture
{
if (showPopupValue) {
return;
}
NSInteger index = [arrayOfChildVCs indexOfObject:selectedViewController];
index = MAX(index-1, 0);
UIViewController *newSubViewController = [arrayOfChildVCs objectAtIndex:index];
endFrame.origin.x = 1024;
startOfNewVCFrame.origin.x = -1024;
[self transitionFromViewController:selectedViewController toViewController:newSubViewController];
selectedViewController = newSubViewController;
}
- (void) populateChildVCList
{
if (self.currentactivity == EPI_Normal)
{
arrayOfImageNames = [[NSArray alloc]initWithObjects:#"AD_Initiate_SPI_Normal.jpg", #"AD_Initiate_CPI_Normal.jpg", #"AD_Initiate_EAC_Normal.jpg", #"AD_Initiate_PV_Normal.jpg", #"AD_Initiate_EV_Normal.jpg", nil];
}
else
{
arrayOfImageNames = [[NSArray alloc]initWithObjects:#"AD_Initiate_SPI_Trigger.jpg", #"AD_Initiate_CPI_Trigger.jpg", #"AD_Initiate_EAC_Trigger.jpg", #"AD_Initiate_PV_Trigger.jpg", #"AD_Initiate_EV_Trigger.jpg", nil];
isTriggerOn = YES;
}
arrayOfChildVCs = [[NSMutableArray alloc] init];
[arrayOfChildVCs addObject:[[PopupDummyViewController alloc]initWithNibName:#"PopupDummyViewController" bundle:nil]]; // Note: Add one dummy VC to initiate swap
for (int vcIndex = 0; vcIndex < [arrayOfImageNames count]; vcIndex++)
{
PiSLAComplianceViewController *childPopupController = [[PiSLAComplianceViewController alloc]initWithNibName:#"PiSLAComplianceViewController" bundle:nil];
childPopupController.popUpImageName = [arrayOfImageNames objectAtIndex:vcIndex];
childPopupController.imageIndex = vcIndex;
childPopupController.isTriggerOn = isTriggerOn;
[arrayOfChildVCs addObject:childPopupController];
}
selectedViewController = [arrayOfChildVCs objectAtIndex:0];
selectedViewController.view.frame = CGRectMake(0, 100, 100, 511); // Took the imageview coordinates
// Add the dummy view controller to Container View Initially
[self addChildViewController:selectedViewController];
[self.view addSubview:selectedViewController.view];
// notify it that move is done
[selectedViewController didMoveToParentViewController:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[super viewDidLoad];
UISwipeGestureRecognizer *swipeGestureRecognizerRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGestureRight:)];
[swipeGestureRecognizerRight setDirection:UISwipeGestureRecognizerDirectionRight];
[ self.view addGestureRecognizer:swipeGestureRecognizerRight];
UISwipeGestureRecognizer *swipeGestureRecognizerLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeGestureLeft:)];
[swipeGestureRecognizerLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[ self.view addGestureRecognizer:swipeGestureRecognizerLeft];
endFrame = deliverableimageview.frame;
startOfNewVCFrame = deliverableimageview.frame;
[self populateChildVCList]; // To Create list of child view controllers and loads one invisible dummy view controller to be ready for swiping
}
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
if (fromViewController == toViewController)
{
// cannot transition to same
return;
}
// animation setup
toViewController.view.frame = startOfNewVCFrame;
// notify
[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];
// transition
[self transitionFromViewController:fromViewController
toViewController:toViewController
duration:1.0
options:0
animations:^{
toViewController.view.frame = fromViewController.view.frame;
fromViewController.view.frame = endFrame;
}
completion:^(BOOL finished) {
[toViewController didMoveToParentViewController:self];
[fromViewController removeFromParentViewController];
}];
}

using NSMutableArray to change subviews

I have creates an array of three viewControllers which I would like to swipe between. and have animate across the screen.
So far I have created the array of views, have gesture control and am loading the first view of the array to the view in the viewDidLoad method of the viewController thats holding my animation stuff.
What I have done is added to viewController objects, (current, furutre) when the app first loads I put the first view of the array into the current viewController.. then when I swipe the view I Load the next view int he array into the future viewcontroller and perform an animation.. Then I do the same for the third animation.. however its breaking down, because I am not passing the second view to current then the third view to future before the last animation.. (hope this makes sense.)
Heres the code thats doing what I am doing so far..
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = #"Prototype";
//Initalizse the swipe gestuer listener
[self setupLeftSwipeGestureRecognizer];
[self setupRightSwipeGestureRecognizer];
//Initalize all of the swipe views
DetailViewController *DVCA = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
DetailViewControllerB *DVCB = [[DetailViewControllerB alloc] initWithNibName:#"DetailViewControllerB" bundle:[NSBundle mainBundle]];
DetailViewControllerC *DVCC = [[DetailViewControllerC alloc] initWithNibName:#"DetailViewControllerC" bundle:[NSBundle mainBundle]];
//Assinge swipeviews to viewArray
viewArray = [NSArray arrayWithObjects:DVCA, DVCB, DVCC, nil];
//Initalize viewcount so it can keep track of which viewController is in view
viewCount = 0;
// set detail View as first view
currentViewController = [viewArray objectAtIndex:viewCount];
[self.view addSubview:currentViewController.view];
}
// Need to change this to work with viewArray
- (void)swipedScreen:(UISwipeGestureRecognizer*)gesture {
//Left swipe
if (gesture.direction == UISwipeGestureRecognizerDirectionLeft) {
//stops swipes from returning any viewCount outside of viewArrays range
if ((viewCount >= 0) || (viewCount >= 2)) {
//Increment for next view
viewCount += 1;
futureViewController = [viewArray objectAtIndex:viewCount];
[self.view addSubview:futureViewController.view];
[futureViewController.view setFrame:CGRectMake(320, 0, self.view.frame.size.width, self.view.frame.size.height)];
[UIView animateWithDuration:0.25 animations:^{
[futureViewController.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[currentViewController.view setFrame:CGRectMake(-320, 0, self.view.frame.size.width, self.view.frame.size.height)];
}];
}
}
//Right swipe -- still need to do this (go back through the view array.
else if (gesture.direction == UISwipeGestureRecognizerDirectionRight){
[UIView animateWithDuration:0.25 animations:^{
[self.detailViewA.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.detailViewB.view setFrame:CGRectMake(320, 0, self.view.frame.size.width, self.view.frame.size.height)];
}];
}
}
Sorry but you should use a UInavigationController to switch between views of view controller.
You can stillanimate the frame and not use the classic animation included in uinavigation controlller.
you push and pop view controller in the navigation controller. look for UINavigationController in the apple doc, you dont need to have the navigation bar at the top if that's what you're trying to avoid with your code.

how to get a popover frame of specified width and height in ipad

i am using an popover view in my application,when i went through the samples i found how to create a popover view but in the sample code the popover view is getting displayed to whole page. i want the popover frame of specified width and height when i click the button.
-(IBAction) settingsGo:(id) sender{
NSLog(#"Go");
if (self.popoverController == nil)
{
PopOver *lang = [[PopOver alloc]
initWithNibName:#"PopOver" bundle:[NSBundle mainBundle]];
UIPopoverController *popOver =
[[UIPopoverController alloc]initWithContentViewController:lang];
popOver.delegate = self;
[lang release];
self.popoverController = popOver;
[popOver release];
}
CGRect popoverRect = [self.view convertRect:[button frame]fromView:[button superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 50);
[self. popoverController
presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
so what changes i should make in the above code to get a frame of specified size of width and height.
Account is the class to be displayed. popAccount is its instance. buttonA is the button on which after click the popOver will be displayed.
-(void)viewDidLoad
{
popAccount = [[Account alloc] init];
//[popAccount setDelegate:self];
popOverControllerA = [[UIPopoverController alloc] initWithContentViewController:popAccount];
popOverControllerA.popoverContentSize = CGSizeMake(200, 200);
}
-(IBAction)togglePopOverControllerA {
if ([popOverControllerA isPopoverVisible]) {
[popOverControllerA dismissPopoverAnimated:YES];
} else {
[popOverControllerA presentPopoverFromRect:buttonA.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
Further ask for any query..
Set popoverController.popoverContentSize to whatever size you want.
In the root view to position
CGRect frame= CGRectMake(0,0, 0, 0);
[self.myPickerPopover presentPopoverFromRect:frame inView:self.view permittedArrowDirections:0 animated:NO];
To size in the view controller contents being displayed in the popover
-(void)viewDidLoad
{
self.contentSizeForViewInPopover = CGSizeMake(750,880);
}

How can I see lastest subView after clicking popover embedded in NavigationView?

When click button, a popoverView embedded in NavigationView appear.
My code is as follows:
-(IBAction)myStuffPOP:(id)sender
{
if(myStuffListViewController ==nil)
{
myStuffListViewController = [[MyStuffListViewController alloc] init];
}
UINavigationController *navcontroller=[[[UINavigationController alloc] initWithRootViewController:myStuffListViewController] autorelease];
// Here we create popover controller.
mystuffPopoverView = [[UIPopoverController alloc] initWithContentViewController:navcontroller] ;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 100);
popoverRect.size.height = 40;
[mystuffPopoverView presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
[navcontroller setNavigationBarHidden:NO];
}
In NavigationView of PopoverView :
1st subView ---> 2nd SubView ---> 3rd Subview
If I touch 3rd SubView, PopoverView disappears.
My Question is :
When I click button again, I wanna to see lastest View - 3rd SubView not 1st SubView.
Declare UINavigationController *navcontroller; in .h file
Create only onсe navcontroller with your root view controller,
in viewDidLoad method, for example.
- (void)viewDidLoad {
myStuffListViewController = [[MyStuffListViewController alloc] init];
navcontroller=[[UINavigationController alloc] initWithRootViewController:myStuffListViewController]; }
Show UIPopoverController with exist navigation stack
-(IBAction)myStuffPOP:(id)sender {
//Here we create popover controller.
mystuffPopoverView = [[UIPopoverController alloc] initWithContentViewController:navcontroller] ;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 100);
popoverRect.size.height = 40;
[mystuffPopoverView presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
[navcontroller setNavigationBarHidden:NO]; }
Don't forget to release objects
- (void)dealloc {
[myStuffListViewController release];
[navcontroller release];
}
No need to create UINavigationController every time. Save it the same way as MyStuffListViewController
if ( myNavigationController == nil )
myNavigationController = [[[UINavigationController alloc] initWithRootViewController:myStuffListViewController] autorelease];

How does autosize work in iPhone SDK?

I'm trying to do the following:
alt text http://img101.imageshack.us/img101/7396/33959221.png
I need to do a lot of custom things, so I subclassed everything.
alt text http://img248.imageshack.us/img248/4201/49422483.png
I'm having issues with autoresize and positioning. For instance the UIToolBar is not at the correct position.
So here is the question:
If you don't use UITableViewController or any other Controller, that takes care of all the positioning and sizing, then you have to do it yourself.
Can someone someone tell me how this works? What do I need to understand?
---- UPDATE:
My custom goals are actually not that important as my question is actually about something else. But OK. So all "elements" like the TableView, the Toolbar and the TabBar will have custom backgrounds and use custom buttons. The TableView will be GroupedStyle and the groups can be collapsed.
My question is how do I have to structure my code especially regarding positioning and autoresizing in order to achieve what you can see in picture #1.
This is how it's structured right now:
Application Delegate:
- (void) loadView {
RootViewController *rootView = [[RootViewController alloc] init];
[window addSubview:rootView.view];
[window makeKeyAndVisible];
RootViewController:
- (void) loadView {
self.theView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.theView.autoresizesSubviews = YES;
self.theView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.view = self.theView;
ChildViewController *childView = [[ChildViewController alloc] init];
[self.view addSubview:childView.view];
ChildViewController:
- (void) loadView {
self.theView = [[UIView alloc] init];
self.view = self.theView;
}
- (void) viewDidLoad {
self.view.frame = [[UIScreen mainScreen] bounds];
CGRect toolbarBounds = self.theToolbar.bounds;
CGRect viewBounds = self.view.bounds;
CGRect tableViewBounds = CGRectMake(0, CGRectGetHeight(toolbarBounds), CGRectGetWidth(viewBounds), CGRectGetHeight(viewBounds) - CGRectGetHeight(toolbarBounds));
self.view.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.theTableView = [[MyTableView alloc] initWithFrame:tableViewBounds
style:UITableViewStyleGrouped
parent:self];
[self.view addSubview:self.theToolbar];
[self.view addSubview:self.theTableView];
}
MyToolBar:
- (id)initWithParent:(id)theParent {
if ((self = [self init])) {
self.parent = theParent;
CGRect rectArea = CGRectMake(0, 0, CGRectGetWidth([[[self parent] view] bounds]), 44);
[self setFrame:rectArea];
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self loadButtons];
}
return self;
}
So this is how the positioning is structured at the moment (messy). It actually works, BUT I have a ModalView which is handled by the ChildViewController. When I have the iPad in Portrait view and I pop up the modal view and dismiss it, then everything works. But when I do the same on Landscape view it rotates the hole view... the ChildViewController by 90 degrees when dismissing the modal view. Very strange. When I load directly ChildViewController in my AppDelegate, then again everything works fine.
You're missing the UIViewAutoresizingFlexibleBottomMargin option in the autoresize mask of your toolbar, for instance.