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
Related
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?
I can't find this anywhere. So, if you possess the info about it, please give me a link.
I have one view controller, I made a menu for a simple game. There are some buttons on it.
I have another view controller and there some buttons too.
The question is:
"How I can do an animation of this buttons (hiding off the screen) after I choose one button that triggers a custom segue (without any animation) to another View Controller, which will run it's button animation(coming to the screen from a border of the screen)?"
I made this like this:
1) Theory: I make a IBAction for a menu button, then in this IBAction I call an animation method, which call a performSegueMethod:. After this in new VC in viewWillAppear method call a animation method (that almost equal method from source VC). All this works, but this don't look smooth. The problem with this animation occurs when destination VC replace source VC. There is some split second, when all looks static, and only after this animation starts.
I don't know how to remove this destination VC lag. May be I must load a destination view before a segue? I tried to do this, but may be a made something wrong, or it's just don't help me.
2) Practice:
firstViewController.m:
- (IBAction)newGameSegueButton {
[self menuSlideInDirection:#"CenterToLeft" performingSegueWithIdentifier:#"mode"];
}
-(void)menuSlideInDirection:(NSString *)direction performingSegueWithIdentifier:(NSString *)segueIdentifier
{
[UIView animateWithDuration:0.4 animations:^{
CGPoint newGameButtonCenter;
newGameButtonCenter.x = directionIndex * 160;
newGameButtonCenter.y = self.gameButtonSlide.center.y;
self.gameButtonSlide.center = newGameButtonCenter;
[UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
//some animation too
} completion:nil];
[UIView animateWithDuration:0.2 delay:0.2 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
//animation
} completion:nil];
[UIView animateWithDuration:0.1 delay:0.3 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
//some animation too
} completion:^(BOOL finished){
if(segueIdentifier){
[self performSegueWithIdentifier:segueIdentifier sender:self];
}
}];
}];
}
Okay, then custom segue code is pretty simple:
-(void)perform
{
UIViewController *src = self.sourceViewController;
UIViewController *dst = self.destinationViewController;
[src.navigationController pushViewController:dst animated:NO];
}
And my secondViewController.m:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self menuSlideInDirection:#"RightToCenter" performingSegueWithIdentifier:nil];
}
menuSlideInDirection:#"RightToCenter" performingSegueWithIdentifier:nil in secondViewController identical to method with same name in firstView.
I'm looking for smooth animation of particular objects of destination view controller right after a segue.
May be a doing all wrong and there a another way to do this? (I only think of adding all view and all controls of destination VC to source VC and remove "destination VC" at all).
Hope, somebody can help me with this.
Try doing all first view controller's animations in perform method.
As for the second view controller's animations, I don't think there is any other 'good' way than doing it in viewWillAppear (although I would prefer viewDidAppear) since the outlets of the destination view controller are not set while performing the segue(they will be nil). In other words, you do not have a way to access your buttons, let alone animate them.
A hackish way would be to call [segue.destinationViewController view] before perform so that the destination view controller's view hierarchy is loaded and the outlets are set. Then perhaps, you may animate buttons in the destination view controller in perform before pushing it onto navigation stack.
For my question, I choose the way of putting two views under the same VC. Animation is smooth and it's look much better than using perform / viewWillAppear method.
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.
I am confused as to Storyboards in iOS. I want to use them and have my code be as modern as possible, but somewhat confused. Here is my problem:
In the main view of my app, you click a button and some time-consuming things happen behind the scenes (music plays, some files are concatenated). While this is happening, I want a menu with some text fields to slide up and let the user enter some info, and then he will click a button to dismiss this menu.
This menu can cover the full screen, but I don't want to segue to a new Storyboard entirely, because there is stuff going on in the background and we'll need to come back to the main view soon.
One thing I tried was to create a new storyboard for this menu and load it using instantiateViewControllerWithIdentifier, which works, but then I can't dismiss it later without the app crashing. But maybe there is a better way anyway? What is proper programming style on this?
Someone asked about my code, I think this is the only place I can put it? Here it is. In the main view:
AddInfoController *infoSheet = [[AddInfoController alloc] init]; //subclass of viewcontroller
infoSheet = [self.storyboard instantiateViewControllerWithIdentifier:#"AddInfoView"];
[self.view addSubview:infoSheet.view];
then in my AddInfoController class I have:
- (IBAction)clickedDoneButton:(id)sender {
[self removeFromParentViewController];
}
and in the AddInfoView storyboard, I have a button which is hooked to that IBAction. When it crashes, nothing appears in NSLog, it shows me some hex stuff in Thread 1 and a EXC_BAD_ACCESS error
Ok - if you are bent on using Storyboards and the app keeps crashing when you present the dismiss button, there's most certainly an error you are making. The console error message would be helpful. What are you seeing there.
If Storyboards is taking too much of my time, I would do it programmatically and simply present a Modal View. If you haven't tried before, try presenting a view controller modally. You can learn more about it here.
Create a UIView and UITextViews programmatically and them to the main view. Try something like this:
UIView *someView = [[UIView alloc]initWithFrame:CGRectMake(20, 20, 280, 420)];
UITextField * someTextField = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 240, 44)]; // create uitextfield or something else as much as you want.
[someView addSubview:someTextField];
[someTextField release];
[self.view addSubview:someView];
[someView release];
And create a action button to dismiss the view.
It looks like you are calling removeFromParentViewController but you never actually add it as a child. I don't know if that is what is actually calling the crash, but basically the format to use is:
taken from Apple:
- (void) displayContentController: (UIViewController*) content
{
[self addChildViewController:content]; // 1
content.view.frame = [self frameForContentController]; // 2
[self.view addSubview:self.currentClientView];
[content didMoveToParentViewController:self]; // 3
}
Then after you are finished you call the equivalent methods in reverse:
- (void) hideContentController: (UIViewController*) content
{
[content willMoveToParentViewController:nil]; // 1
[content.view removeFromSuperview]; // 2
[content removeFromParentViewController]; // 3
}
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.