Transition from view (one of the options) in slide out menu to another option in menu with button press and WITH navigation bar - ios

For testing purposes, I'm using the demo that's provided on Github. Search SASlideMenu to find the github repo.
Screenshot 1:
Screenshot 2:
Ok, so I'm using SASlideMenu in my app and here is what I want to do:
In a nutshell, I want to go from the blue page (the one with the button that says "Press me to get to screenshot 1") with a button press, to another one of the options in the menu. I've added the option to get to screenshot 1 to the menu and clicking on this it takes me to that view WITH the navigation bar at the top.
The problem is, when I press the "Press me to get to Screenshot 1" button, it takes me to the screenshot 1 page without the navigation bar at the top of the view. I've used a modal segue to link the button to the view shown in screenshot 1.
I want this view to have the navigation bar just like in the blue screenshot.
Is this possible?
I hope this is clear. If you need any clarification, feel free to ask.

You can't reuse that top bar in different view's as it is here
But following may be solution
1. If top bar is navigation bar then use push segue instead of modal and setup buttons again
2. If you want to use same top bar, just mimic modal view presentation by writing custom segue
//code to mimic modal presetation will be similar to this
- (void)perform
{
//add as subview with origin y at bottom -50
CGRect frame = [[self destinationViewController] view].frame;
frame.origin.y = [[self sourceViewController] view].frame.size.height -50;
[[self destinationViewController] view].frame = frame;
[[[self sourceViewController] view] addSubview:[[self destinationViewController] view]];
//animate frame with new y postion
[UIView animateWithDuration:0.5 animations:^{
CGRect frame = [[self destinationViewController] view].frame;
frame.origin.y =[[self sourceViewController] view].frame.origin.y - SOME_OFFSET_VALUE_TO_SHOW_TOP_BAR;
[[self destinationViewController] view].frame = frame;
}];
}
3. If you dont wan't modal segue, then just use custom segue like in 2. and add your view (white one) as subview in area below navigation bar

Related

Create a submenu iOS

I want to create a submenu that will appear right next to the first menu and that will contain more options. The first menu is hidden and only appears when a button its clicked on the navigation bar, i used the SWRevealViewController from github for the first menu, but i can't make the second one appear . Can somone help ?
Thanks for any help in advance
Basically you add another SWRevealController as front view controller of the root SWRevealController.
UIViewController *secondRearVC = // your second level menu controller
UIViewController *secondVC = // your second level front view controller
SWRevealViewController *childRevealController =
[[SWRevealViewController alloc] initWithRearViewController:secondRearVC frontViewController:secondVC];
[rootRevealController setFrontViewController:childRevealController animated:YES];
You can find example of what I've suggested here.
Other option is using other side menu controller, JASidePanels, if I'm not wrong it does what you want. Anyway you'll end up using some UIViewController containers recursively, so it's just a matter of choice.
For this effect i have created a separate view say reveal view with UITableView init, at first i am giving zero width and full height for that view. If the navigation button is pressed , i am moving the main view to right like about 100px and change the width of the reveal view to 100px, place that code in animation block.
[UIView animateWithDuration:0.5 animations:^{
//Move frame or transform view
revealView.frame = CGRectMake(0,0,1,screenHeight);
mainView.frame = CGRectMake(0, 0, 320, screenHeight);
}];

Off by 20 pixels (y axis) when adding subview myNavigationController.view

I have a navigation controller with a menu button. When the menu button is pressed, the current view (complete with its navigation bar) should slide to the right, and a menu should simultaneously and contiguously slide in from the left. The details are explained in the comments in the code, below.
It works except in one regard. The current view (in this case, "Conversations"), when added back into the container view I implement, has to have its frame set to "y.min"=-20, or else there are 20 pixels above its navigation bar. However, when I set its y.min to -20, this shifts everything within its view up by 20 pixels. So when the menu button is pressed, everything in the current view suddenly jumps upwards by 20 pixels.
I can't figure out why this is happening or how to correct this. It is also possible that there's an easier way to go about all of this, but I'm not aware of one.* (*I'm not interested in third-party files. I want to learn to do this myself.)
Here is the code:
- (IBAction) showMenu:(id)sender
{
// get pointer to app delegate, which contains property for menu pointer
AppDelegate *appDelegate = getAppDelegate;
//create container view so that current view, along with its navigation bar, can be displayed alongside menu
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 548.0f)];
[container setBackgroundColor:[UIColor blueColor]];
//before presenting menu, create pointer for current view, to be used in completion routine
UIView *presenter = self.navigationController.view;
//present menu's VC. it is necessary to present its (table) VC, not just add its view, to retain the functionality of its cells
[self presentViewController:appDelegate.menuVC animated:NO completion: ^{
//obtain a pointer to the menu VC's view
UIView *menuTemp = appDelegate.menuVC.view;
//replace menu VC's view with the empty container view
appDelegate.menuVC.view = container;
//add the menu view to the container view and set its frame off screen
[container addSubview:menuTemp];
menuTemp.frame = CGRectMake(-260.0f, 0.0f, 260.0f, 548.0f);
//add the the view that was displayed when the user pressed the menu button. set its frame to fill the screen as normal
[appDelegate.menuVC.view addSubview:presenter];
presenter.frame = CGRectMake(0.0f, 0.0f, 320.0f, 548.0f);
//animate the 2 subviews that were just added; "PRESENTER"'S FRAME IS THE ISSUE
[UIView animateWithDuration:25.3f delay:0.0f options:nil animations:^{
[menuTemp setFrame:CGRectMake(0.0f, 0.0f, 260.0f, 548.0f)];
[presenter setFrame:CGRectMake(260.0f, -20.0/* or 0 */f, 320.0f, 548.0f)];
} completion:nil];
}];
}
Here is an illustration of my two options (click for higher resolution):
screen 1) The first screen shows the view before clicking the menu button.
The next two screens show two possibilities as the menu transition animation begins.
screen 2) This is what the transition looks like when I set presenter.frame.y.min to -20. As you can see, the button in the view has jumped up by 20 pixels.
screen 3) This is what the transition looks like when I set presenter.frame.y.min to 0. As you can see, a bar 20 pixels tall is present at the top. The blue color indicates the container view.
I had this problem some time ago when I didn't create my view controller tree correctly. My 20px off was caused by adding a UINavigationController view as a subview. I talked with the Apple Engineers in the labs at WWDC that year. They said I was using the navigation controller incorrectly, it needs to be a top level construct and you shouldn't put it in another UIViewController. That said you can put them in a container view controller like UITabBarController and UISplitViewController.
Your issue is not in the code you've posted it is in the architecture of your view controllers. I've uploaded a sample app to GitHub showing how to create a "Slide Menu" App like the FaceBook and StackOverflow iPhone Apps. See https://github.com/GayleDDS/TestNavBarOffBy20.git
The sample app uses a storyboard with Container Views in the root view controller to manage a UINavigationController (main view) and UITableViewController (menu view).
Now show Menu
See commit message cfb2efc for creation details. I started with the Single View Application template and you need to add the QuartzCore framework.

How do I draw main view underneath my UINavigationBar so when the bar shows/hides, the view is unaffected?

Here's the situation:
I am making an app for iPad w/ iOS 6 using Autolayout along with UINavigationController. What I am trying to do is:
Segue from one view controller to the next with a standard push segue.
When I arrive at the new view controller, hide the nav bar with animation.
As the nav bar hides, I want my view to not shift at all. In fact, I want my view to effectively be drawn underneath the nav bar from the beginning, so I'm left with no shifting or movement of content and no black bars. For reference, this is what happens in the Amazon Kindle app when you go into a book.
With my current code, the contents of my view shift up to fill in the void left by the UINavigationBar.
I've tried force-setting the frame of my UIViewController's view and my UINavigationController's view to the entire iPad screen in the viewWillAppear method of my viewcontroller but no dice. I've experimented w/ Constraints in Autolayout but that also didn't get me to where I wanted to go.
Any help you can give would be great!
Try following before animating the navigation bar:
self.navigationController.navigationBar.alpha = 0.99f;
I didn't try this but this should work.
Looks like you need to add custom navigation bar in your new view and animate it to disappear.
I think, hiding original Navigation bar of Navigation Controller without shifting the view is not possible.
Rather add UINavigationBar to xib file, bind it to IBOutlet uiNavigationBar and try following code
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGRect f = self.uiNavigationBar.frame;
f.origin = CGPointMake(f.origin.x, f.origin.y - 44);
self.uiNavigationBar.frame = f;
} completion:^(BOOL finished) {
NSLog(#"done");
}];
}

Is it correct to move the navigation bar frame?

I have a navigation bar based ipad app.
At some point I want to push another view controller into the views controller hierarchy. Then, when the users tabs some button I want to show a leftMenu controller. To do so I have two views:
A content view which has all the content
And a not visible view which is the leftMenu. This one is under the content view.
So when the user presses the button, what Im doing right now is moving the content view and the navigation bar to the right to make the leftMenu visible:
self.navigationController.navigationBar.frame = CGRectMake(271.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.self.navigationController.navigationBar.frame.size.height);
self.contentView.frame = CGRectMake(271.0, self.contentView.frame.origin.y, self.contentView.frame.size.width, self.contentView.frame.size.height);
This is working, but the first row in the left menu is not "clickable" where the nav bar is supossed to be. Its like the navigation bar is still there capturing the tab events.
Is it correct to do?:
self.navigationController.navigationBar.frame = CGRectMake(271.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.self.navigationController.navigationBar.frame.size.height);
If not, whats the propper way to achieve what I want?
Heres and image ilustrating what the problem is:
I think it's best to use a custom container controller to do this kind of thing, rather than moving a navigation bar. In IB, this can be set up quite easily. Start with a UIViewController, add a container view to it, and size how you want. Then in the inspector, set its x value to minus its width, which will put it off screen to the left. Then add another container view and size it to be full screen. You can then delete the view controller that you got with that container view, and right drag from the container view to your initial navigation controller (of your already setup UI) to connect it up with an embed segue. The UIViewController that you started with should be made the initial view controller of the storyboard. To move in the side view, I use this code in that custom container controller:
-(void)slideInLeft {
if (isRevealed == NO) {
[UIView animateWithDuration:.6 animations:^{
leftView.center = CGPointMake(leftView.center.x + 100, leftView.center.y);
mainView.center = CGPointMake(mainView.center.x + 100, mainView.center.y);
} completion:^(BOOL finished) {
isRevealed = YES; ;
}];
}else{
[UIView animateWithDuration:.6 animations:^{
leftView.center = CGPointMake(leftView.center.x - 100, leftView.center.y);
mainView.center = CGPointMake(mainView.center.x - 100, mainView.center.y);
} completion:^(BOOL finished) {
isRevealed = NO;
}];
}
}
leftView and mainView are IBOutlets to the 2 container views. I call this method from a button in the main view controller (the root view controller of the navigation controller that's embedded in the large container view):
-(IBAction)callSlideIn:(id)sender {
[(ViewController *)self.navigationController.parentViewController slideInLeft];
}
I found a "fast" way to achieve this (and a bit hacky imo)
I added the leftMenu view to the top view in the views hierachy:
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window)
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[[[window subviews] objectAtIndex:0] addSubview:self.leftMenu.view];
Now it is les deep than the navigation bar and, of course, its clickable

How to hide custom tab bar button when hidesBottomBarWhenPushed is "TRUE"

I am using the code snippet from Tito to add a custom button to my tab bar:
https://github.com/tciuro/CustomTabBar
(Subclassing UITabbarController and adding a custom button using
// .. created a UIButton *button
[self.view addSubview:button];
)
This works great with my storyboard-based app except for the case of a subview within a navigation controller with the option "Hides bottom bar on push" enabled.
This hides the tab bar as promised, but not the custom button.
Seems like the button should be added as a subview to the tab bar itself?
I tried this ugly code which did not even make the button show up:
for(UIView *view in self.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view addSubview:button];
break;
}
}
Any ideas?
UPDATE:
My solution:
In my ApplicationDelegate i define the following methods, which i call whenever needed in the viewWillAppear or viewWillDisappear methods:
-(void)hideCenterButton:(BOOL)animated
{
if(animated){
[UIView animateWithDuration:0.3
delay:0.0f
options:UIViewAnimationCurveLinear
animations:^{
CGRect frame = self.centerButton.frame;
frame.origin.x = -100;
self.centerButton.frame = frame;
}
completion:^(BOOL finished){
}];
}
}
-(void)showCenterButton:(BOOL)animated
{
if(animated){
[UIView animateWithDuration:0.35
delay:0.0f
options:UIViewAnimationCurveLinear
animations:^{
CGRect frame = self.centerButton.frame;
frame.origin.x = (self.view.superview.frame.size.width / 2) - (self.centerButton.frame.size.width / 2);
self.centerButton.frame = frame;
}
completion:^(BOOL finished){
}];
}
}
I had to set the animation's duration to 0.35s to get a smooth effect in harmony with the tab bar.
Why don't you make button your tabbar's part.
tabBarController.tabBar.addSubView(yourButton)
everything would be solve. cheers!
One easy way to handle this would be to create an instance of the button in .h of your file.
UIButton *customTabButton;
When calling the hides bottom bar on push set the button property to hidden and reset it again in the other views if the bottom bar is visible.
shareFbButton.hidden=YES;
You can check this is the viewDidLoad of all the files and put this line of code if needed to make sure you are displaying the button and hiding the button on all the pages you need.
if(self.tabBarController.tabBar.isHidden){
// set or reset the custom button visibility here
}
This is one way.
I think there are 2 ways you can got with this.
1) try to get the button into a view that is above the old top view controller and the tab bar BUT below the new top view controller that is pushed.
2) animate away the button when the new view controller is pushed.
The first will require mucking with the iOS proprietary view hierarchy which is undocumented, unsupported and could change anytime.
The second will be a matter of making the animation appear smooth enough for your user not to notice. It's not entirely a matter of behaving perfect, just appearing appropriately.
I would personally recommend an animation of the the button disappearing (animate it's alpha to 0) and reappearing based on if your view controller that goes over the tab bar is appearing or disappearing.
The animation for a navigation is (I believe) 0.3 seconds. If the button is in the middle of the tab bar, you'll likely want it invisible as the animating in view controller reaches it (if not sooner) so something between 0.1 and 0.15 seconds could be used to animate it out.
Now this does not make the button behave exactly the same as the tab bar, but with the quickness of the transition being so short, it will be unnoticeable really to the user.
Now just to provide a question for you to ask yourself. Why do you need to push a view controller that overlaps the tab bar? Why is that more desirable/necessary than presenting a modal view controller? If you can strongly argue for it, keep at it and good luck, if it's not necessary however, you may be able to achieve the experience you want with a modal view controller.
Check this one to put a button on the UITabBar. See if it works after with hidesBottoBarWhenPushed.

Resources