conceptual or technical issue with Cocoa programming - ios

I find myself in need of access to a viewcontroller from its view.
Here is the method
-(void)changePageView:(UIViewController*)newviewcont withtransitiontype:(int)t andtransitionspeed:(int)s
{
//Remove whatever view is currently loaded at index 0, this index is only to be used by "page" views
UIView *oldview = [self.view.subviews objectAtIndex:0];
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:s];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[newviewcont viewWillAppear:YES];
//[oldview viewWillDisappear:YES];
[oldview removeFromSuperview];
[self.view insertSubview:newviewcont.view atIndex:0];
//[oldview viewDidDisappear:YES];
[newviewcont viewDidAppear:YES];
}
Basically, I am trying to write a generic view switch method that is called by the root controller to swap out subviewcontorllers views from the rootcontrollers view.
I pass in a subviewcontroller and am able to remove the current subview. But in order to do proper view switching animation i need access to the current views view controller. Is this the wrong approach and can it be done?

I added a member to the rootcontroller that hold onto the current sub view controller (currentController) and refers to it when a controller swap is done
-(void)changePageView:(UIViewController*)newviewcont withtransitiontype:(int)t andtransitionspeed:(int)s
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:s];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[newviewcont viewWillAppear:YES];
[self.currentController viewWillDisappear:YES];
[self.currentController.view removeFromSuperview];
[self.view insertSubview:newviewcont.view atIndex:0];
[self.currentController viewDidDisappear:YES];
[newviewcont viewDidAppear:YES];
[UIView commitAnimations];
self.currentController = newviewcont;
}

The changeView() method belongs in the viewcontroller. It would solve you problem of having the view knowing about it's controller (which it shouldn't) and it makes more sense.
Also unless you are doing something fancy in changeView() that can't be done using the methods in a UIViewController object then you should just use it instead, if it is neccesary to implement your own view switching method then you can extend UIViewController instead of implemtning part of the view controlelr in your view.
my 2 cents :)

I believe your approach is wrong. You should look into UINavigationController I believe.

Related

Custom Segue Flashes

I am using the following code to override the perform method in a custom segue to achieve sliding effect when moving between view controllers.
- (void)perform
{
MasterController *sourceController = (MasterController *)self.sourceViewController;
MasterController *destinationController = (MasterController *)self.destinationViewController;
CGRect frame = sourceController.view.frame;
[sourceController.view addSubview:destinationController.view];
[destinationController.view setFrame:CGRectOffset(frame, frame.size.width, 0)];
[UIView animateWithDuration:0.5 animations:^{
[sourceController.view setFrame:CGRectOffset(frame, -frame.size.width, 0)];
} completion:^(BOOL finished) {
[sourceController presentViewController:destinationController animated:NO completion:nil];
[destinationController.view removeFromSuperview];
}];
}
Similar to this code exists all over the internet. the problem is that "sometimes" after the animation finish the screen flashes/blinks/flickers then gets back normal.
removing [destinationController.view removeFromSuperview]; line of code seems to solve the problem. but, that doesn't look right! right?
Any ideas how to solve this?
Yes, simply remove [destinationController.view removeFromSuperview];. It will be done for you. At the end of the segue, destinationController.view will have a new superview and will be removed from sourceController.view.

Placing iAd over UITabBar in a UITableView, Objective-C & TableView not appearing beneath iAd

I am trying to get a similar result to the post that is shown here: https://stackoverflow.com/questions/28866171/place-iad-over-a-uitabbar
So this is what i did to achieve this:
One side question here: Is it normal that i can't drag the banner all the way?
And using this i get this result:
Nevermind that the iAd dont show. But my real question is why is not the TableView appearing beneath the iAd so i can get the same result as the on in the post? What can i do to make this work?
Thank you all!
Ok i solved this with some more researching and testing.
FIRST OF ALL. You DONT need to use a UITableView inside a UIViewController to make this work. This can be done by having a subclass of UITableViewController which i had from start but i thought i needed to change.
Anyway Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.canDisplayBannerAds = YES;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
banner.frame = CGRectOffset(banner.frame, 0, banner.frame.size.height);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:1];
[UIView commitAnimations];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[banner setAlpha:0];
[UIView commitAnimations];
}
NOTE this method is used when i am not placing an iAd in the storyboard. There is no need to do that when using this method. So no need to think about putting delegates etc..

change transition of navigationcontroller ios

In the typical viewcontroller transition both views, the disappear and appear view are moving, but now I want to create a custom animation where you throw the event to change of view, the view that will disappear, just hide without transition and animation, and the view will appear continue with the same transition.
then the problem here is I have navigation bar and I don't know, how can I create a custom transition of navigation bar?,
can you help me to know how to change or remove the transition of navigation controller.
I've try it but it only add other transition and don't remove the base transition.
For Push:
MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.navigationController pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
For Pop:
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:self.navigationController.view cache:NO];
}];
[self.navigationController popViewControllerAnimated:NO];
any ideas? thanks :D
You can just use add as subview and have title bar to mimic like navigation controller.
MainView *nextView = [[MainView alloc] init];
//setup frame
nextView.view.frame = xxx;
[self.view addSubview:nextView.view];
Remove using [nexView.view removeFromSuperView];
OR
Just add some view above your current view with default hidden and set hidden NO on some action or call bringSubviewFront method if you want to keep view below and bring in front on some action.

Use presentModalViewController but with modeUIViewAnimationTransitionCurlUp

How is it possible that I change the transition for presenting a modal view controller. Is it possible that the presenting transition is using the default UIModalTransitionStyle....
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
but the dismiss transition is using the UIViewAnimationTransitionCurlUp transition. Important is that I don't want to use the UIModalTransitionStylePartialCurl it should be the CurlUp one.
Sadly the following code doesn't work:
[UIView transitionFromView:self.view toView:self.parentViewController.parentViewController.parentViewController.view duration:1.0 options:UIViewAnimationTransitionCurlUp completion:^(BOOL finished) {....}];
Maybe it has something to do that the view controller is displayed in modal mode.
It would be nice if someone can help.
It feels kludgy, but you can do this by animating the transition of adding your destination view controller's view, but on the completion of that, you immediately remove it again and then properly transition to it via the presentViewController (this time without animation, since the visual effect has already been rendered).
I do this in a subclassed custom UIStoryboardSegue (you didn't say NIBs or storyboard, but the concept is the same):
- (void)perform
{
UIViewController *src = self.sourceViewController;
UIViewController *dst = self.destinationViewController;
[UIView transitionWithView:src.navigationController.view
duration:0.75
options:UIViewAnimationOptionTransitionCurlUp | UIViewAnimationOptionCurveEaseInOut
animations:^{
[src.navigationController.view addSubview:dst.view];
}
completion:^(BOOL finished){
[dst.view removeFromSuperview];
[src presentViewController:dst animated:NO completion:nil];
}];
}
Clearly, if your source view controller doesn't have a navigation controller, you would replace those "src.navigationController.view" with just "src.view". But hopefully this gives you the idea.
And, anticipating the logical follow-up question, when dismissing the view controller, I have a button hooked up to an IBAction:
- (IBAction)doneButton:(id)sender
{
[UIView transitionWithView:self.view.superview
duration:0.75
options:UIViewAnimationOptionTransitionCurlDown
animations:^{
[self dismissViewControllerAnimated:NO completion:nil];
}
completion:nil];
}

iPad orientation notifications lost when transition for keyWindow

I have an animation done over the keyWindow of the app.
[UIView beginAnimations:kAnimationLogin context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window_ cache:NO];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[window_ addSubview:splitViewController_.view];
[UIView commitAnimations];
[loginViewController_.view removeFromSuperview];
This works ok. Then, if the user logouts, the transition is the reverse
[UIView beginAnimations:kAnimationLogout context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:window_ cache:NO];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[window_ addSubview:loginViewController_.view];
[UIView commitAnimations];
[splitViewController_.view removeFromSuperview];
Here is the problem. Now, loginViewController_ and splitViewController_ don't receive the orientation notifications. Why?
Well, it's not a great solution but I've found a way to avoid that problem. First of all, I think that the problem comes because, while animation, both view controllers receives the orientation notifications while, I guess, adding and removing to and from the window and raises the problem. I don't know exactly if it's an issue related to view hierarchy (I guess it's correct but I'm not sure) or not.
So, the solution I use is to put the LoginViewController as a ModalViewController of SplitViewController, that is the main controller, and use a FlipHorizontal transition while showing.
That solves the problem.

Resources