Adding view controller view before presenting - ios

Below is my code..
TestTemp1ViewController *temp=[[TestTemp1ViewController alloc]init];
[self.view addSubview:temp.view];
[self presentModalViewController:temp animated:FALSE];
This codes works well in iOS 5.0 but crashes in iOS 6.0.
Crash report: [UIViewController loadViewIfRequired]-- bad excess
I cannot understand why this isn't working in iOS 6.0. Guys, ya I know that's not the good way but what I am trying to do is presentviewcontroller with grow and shrink animation. If I do this after I present then I will get white background of view controller.
Below is my code...
-(void)animateGrowAndShrink:(ViewController *)controller1 {
//self.view.userInteractionEnabled=NO;
[self.view addSubview:controller1.view];
[self presentModalViewController:self.controller animated:FALSE];
if (dayTimeLineIsShown) {
//shrink dayTimeLineIsShown=FALSE;
[UIView beginAnimations:#"animationShrink" context:NULL];
[UIView setAnimationDuration:.61f];
controller1.view.transform=CGAffineTransformMakeScale(.01f,.01f);
} else {
//expand dayTimeLineIsShown=TRUE;
controller1.view.transform=CGAffineTransformMakeScale(0.01,0.01);
[UIView beginAnimations:#"animationExpand" context:NULL];
[UIView setAnimationDuration:.60f];
timeLine.view.transform=CGAffineTransformMakeScale(1, 1);
}
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView commitAnimations];
}
-(void)animationDidStop:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
self.view.userInteractionEnabled=YES;
if ([animationID isEqualToString:#"animationExpand"]) {
[self presentModalViewController:self.controller1 animated:FALSE];
} else {
self.controller.view.hidden=true;
}
}.
Also the controller in which I am doing this is also presented modally if I remove that then it's works in ios 6. Any other idea to achieve zooming and shrinking.

-presentModalViewController and -addSubview are quite different are they're not supposed to be used together. See: When should I use the addSubview method of a view controller?
I think remove the second line or third line will eliminate the error.

I was setting presentation style wrong..It should be like this..
self.modalPresentationStyle = UIModalPresentationCurrentContext;
It should be on current context.So, Now presented view controller view will be drawn on transparent background and not on white background so while shrinking it's view, there will be no white background behind it.

Related

Objective C How to animate Subview with click in Button

I have a problem :D.
I'm currently using a SplitViewController. At the start I want to hide the TableViewController in the MasterView. So i decided to add a SubView in the Storyboard into the tableView, where a little label will be shown.
So after I make my choice in the DetailView and click the Button I want to hide the subView and want to show the tableView. That all with animations.
So here is my Code:
In the TestTableViewController.m
-(void)AnimateView{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
fixedView.frame=CGRectMake(-500, 0,0,0);
[UIView commitAnimations];
NSLog(#"test");
And in the TestDetailViewController.m
- (IBAction)attractionButton:(UIButton *)sender
{
TestTableViewController *testTableViewController = [[TestTableViewController alloc]init];
[testTableViewController AnimateView];
}
I get the NSLog "test" but the Animation is not working.
fixedView is my Subview and I drag it to the header file so it's an IBOutlet.
Thank you so far.
So you seem to instantiate a new ViewController and trying to perform this animation straight away:
TestTableViewController *testTableViewController = [[TestTableViewController alloc]init];
[testTableViewController AnimateView];
The problem is that you don't even present that view controller (its view is not on screen anywhere) so it's normal you don't see any animation.
From my understanding you already have another instance of this view controller presented on screen (am I right?) - so that is the one that you need to use. Pass its pointer to TestDetailViewController in some way (e.g. a property) and then use that object to call your animation method.
PS. I would recommend naming all your methods starting with a lower case letter ;)
The problem is, you are not referencing the same master view controller in your details view controller.
You are creating another one in your IBAction.
In order to get a hold of your (the "original" one) master view controller, do this in your detail view controller:
Create a ivar:
TestTableViewController *masterViewController;
And then to reference it:
masterViewController = (TestTableViewController*)[[[self.splitViewController.viewControllers lastObject] viewControllers] objectAtIndex:0];
For example:
- (IBAction)attractionButton:(UIButton *)sender
{
masterViewController = (TestTableViewController*)[[[self.splitViewController.viewControllers lastObject] viewControllers] objectAtIndex:0];
[masterViewController AnimateView];
}
And finally in your AnimateView method, make change to the following:
[UIView animateWithDuration:0.1f animations:^
{
fixedView.frame = CGRectMake(-500, 0, 0, 0);
}
completion:nil];
Hope this helps.
What you could try is this:
[UIView animateWithDuration:0.15f animations:^{
fixedView.frame=CGRectMake(-500, 0,0,0);
}completion:^(BOOL finished){
}];
Are you sure you can call [UIView beginAnimations: ....] without a first argument?

Incorrect Animation used despite preferredStatusBarUpdateAnimation being called

Popping to a controller and calling the reenteringViewController method show below after view will appear ignores the preferredStatusBarUpdateAnimation set in the view controller and instead uses a Slide Animation (which was used previously in the old controller though is set to fade before popping to the current controller).
-(void)reenteringViewController{
[UIView animateWithDuration:0.7 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^
{
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]) {
[self prefersStatusBarHidden];
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate) withObject:nil];
}
}
completion:^(BOOL finished){
}];
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation{
return UIStatusBarAnimationFade;
}
-(BOOL)prefersStatusBarHidden{
return NO;
}
Has anyone experienced this before and if so if they found a solution? I've spent hours pouring over the code but it's very simple and all seems to be calling things correctly but just doesn't use the correct animation. Seems like it could be an iOS7 bug.
I appreciate your help in advance.

Slide-swipe menu in front of view

I am looking or an library that can help me with an slide-swipe menu that loads in front of the current view; that doesn't push the current view to the side.
I have tried a bunch of different libraries, and can't find one that works for me. Also, I am not using Storyboard and most of those I find use Storyboard.
Among those I tried: SWRevealViewController, ecslidingviewcontroller (Storyboard, but tried to reuse code).
How can I either change SWRevealViewController to load on top of the current view, or is that another library which I must have missed which solved my problem?
Example:
You can hide or show the view using UIViewAnimmation.
Add new file like subviewcontroller and do the add subview for mainviewcontroller.
Try like this..
- (void)viewDidLoad
{
subview =[[subviewcontroller alloc]init];
[self.view addSubview:subview.view];
viewVisible=YES;
[super viewDidLoad];
}
- (IBAction)showHideView {
if (viewVisible) {
[UIView beginAnimations:#"animateImageOff" context:NULL];
[subview.view setFrame:CGRectOffset(subview.view.frame, 150, 0)]; //-view1.frame.size.width
[UIView commitAnimations];
viewVisible = NO;
} else {
[UIView beginAnimations:#"animateImageOn" context:NULL];
[subview.view setFrame:CGRectOffset(subview.view.frame,-150, 0)]; //view1.frame.size.width
[UIView commitAnimations];
viewVisible = YES;
}
}
i found the JTRevealSlideBar to be very nice. you will just need to change how it does its animation so that it doesnt push the viewcontroller out the way
writing your simple custom animation and plug it to ECSlidingViewController should work

How to code a custom segue that "slides" between View Controllers?

I built a app with storyboard, with an initial view controller, connected to many subsequent view controllers, connected sequentially, using cross dissolve segue. These work one swipes. All works fine. However, instead of being forced to use the basic segues, I want to have a custom segue that will slide the view controller content on and off the screen, much like the push for navigationControllers, but, being enabled to go left and right depending if one is going forward or backwards in the app.
I have set the segue to custom, and have created and saved a MySegue.h file. HOWEVER, I don't know how to code a custom segue that will slide one viewcontroller off the screen as the other slides on and back and forth as I move between view controllers.
Can anyone please provide me with come coding (it should be easy!) for a custom segue to move from one view controller to the next and back by sliding the screen on and off so I don't have to use the basic cross dissolve or standard flips offered in Xcode 4.2? I would be most grateful.
I was running into the same issue here, but I was using swipe gestures to go from one view controller to the next. Using the storyboard itself to set up segues was working fine, but when I needed a swipe to "go back" to the previous view controller, the animation went from right-to-left, instead of left-to-right. To fix that issue I did the following:
Embedded a Navigation Controller in the root view controller.
Used segues to push new view controllers.
When I wanted to "go back" to the previous view controller, I did not add a segue to the storyboard to push the previous view controller. Instead, I called the Navigation Controller's popViewControllerAnimated method whenever a back swipe occurred.
To create a custom segue that slides view controllers first create a class that extends UIStoryboardSegue, then override the perform selector. I just made something like this and it should work for you too. Here's my code:
#define kAnimationDuration 0.5
#import "CustomSlideSegue.h"
#implementation CustomSlideSegue
- (void)perform
{
UIViewController *sourceViewController = (UIViewController *) self.sourceViewController;
UIViewController *destinationViewController = (UIViewController *) self.destinationViewController;
[sourceViewController.view addSubview:destinationViewController.view];
[destinationViewController.view setFrame:sourceViewController.view.window.frame];
[destinationViewController.view setBounds:sourceViewController.view.bounds];
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if ( !self.slideLeft ) {
[UIView animateWithDuration:kAnimationDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[destinationViewController.view setCenter:CGPointMake(screenSize.height + screenSize.height/2, screenSize.height/2 - 138)];
[destinationViewController.view setCenter:CGPointMake(screenSize.width/2 + 127, screenSize.height/2 - 138)];
}
completion:^(BOOL finished){
[destinationViewController.view removeFromSuperview];
[sourceViewController presentViewController:destinationViewController animated:NO completion:nil];
}];
} else {
[UIView animateWithDuration:kAnimationDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[destinationViewController.view setCenter:CGPointMake(-1*screenSize.height/2, screenSize.height/2 - 138)];
[destinationViewController.view setCenter:CGPointMake(screenSize.width/2 + 127, screenSize.height/2 - 138)];
}
completion:^(BOOL finished){
[destinationViewController.view removeFromSuperview];
[sourceViewController presentViewController:destinationViewController animated:NO completion:nil];
}];
}
}
Then when you want to perform the segue use this code:
UIViewController *destination = [self.storyboard instantiateViewControllerWithIdentifier:#"some identifier"];
CustomZoomSegue *segue = [[CustomZoomSegue alloc] initWithIdentifier:#"segue vc identifier" source:self destination:destination];
[self prepareForSegue:segue sender:self];
[segue perform];
The CGPointMake calls are custom to my code (I used landscape orientation) but you should be able to change it to fit your needs. If you need further clarification or have any question let me know and I will try to answer.
NOTE: I use storyboards with no segue lines between the view controllers.
Why not just use a UINavigationController? This seems to be exactly what they're designed for.

Hide keyboard when switching to another view

I have 2 views, login and register.
I did [currentTextField resignFirstResponder]; before I navigates to the other view.
The problem is, the keyboard is only hidden after it switched view. Which thus fired the keyboardDidShow method on the other view which messes stuff up.
2011-07-19 18:55:33.315 Prime Taxi Booking[601:207] Login view appear // lauched app
2011-07-19 18:55:34.952 Prime Taxi Booking[601:207] Login Keyboard appear // starts typing
2011-07-19 18:55:37.033 Prime Taxi Booking[601:207] Register view appeared // navigation
2011-07-19 18:55:37.036 Prime Taxi Booking[601:207] Login view disappear
2011-07-19 18:55:37.360 Prime Taxi Booking[601:207] Register Keyboard disappear // ?? how do I make this to disappear login keyboard instead?
I wonder why did it only resignFirstResponder after switching views when I clearly placed it above it.
-(IBAction) registerButton:(id) sender
{
[currentTextField resignFirstResponder];
Registers *registerview = [[Registers alloc] initWithNibName:nil bundle:nil];
[UIView beginAnimations:#"flipping view" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationTransition: UIViewAnimationTransitionCurlUp
forView:self.view.superview
cache:YES];
[UIView commitAnimations];
[self presentModalViewController:registerview animated:YES];
//[self.view addSubview:registerview.view];
}
you can put some delay before going to second view so that keyboard will hide. try [self performSelector: withObject: afterDelay:0.35];//Pass the selector like #selector(displaySecondView) before calling this resign current textfield.

Resources