Swipe down modal VC like in iOS8 MailApp - ios

I want to implement ability swiping down modal VC almost to the end, and with swiping up - return to the place. I tried do it with ECSlidingViewController (with zoom effect), but I have custom tabBar and I couldn't do that. I tried make it easier:
CGRect frame = self.view.frame; //or self.parentViewController.view.frame
frame.origin.x -= 50;
frame.origin.y -= 50;
self.view.frame = frame;
VC changed position, but under it I see white (or black) screen, no the vc from which I pushed. How can I achieve functionality that I want?
(I'm using Xcode 5/iOS 7.1)

I think this new Presentation Style allow what you are looking for.
It does not hides after previous VC after the modal if shown, but it remains behind.
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext
Hope this helps.
G

Related

Cannot detect tap after hiding tabbar

I am using iOS 7. I have a UITableView inside a UITabbarController.
I hide the tabbar using the following code (meanwhile I also set the tableView to be fullscreen)
CGRect frame = self.tabBarController.tabBar.frame;
frame.origin.y = 568.0;
self.tabBarController.tabBar.frame = frame;
However, after that, I cannot select the cell near the bottom. When tap at the position where the tabbar was, there is no effect.
Has anyone run into the same problem? Do anyone know how to fix?
You'll want to use something like This to detect the tab bar and then hide.

Funny UIScrollView when using presentViewController

Summary:
I have a UIScrollView with zoomable content. If the content is NOT zoomed and I presentViewController, everything is fine when I dismiss that ViewController. But, if I have zoomed the content and then presentViewController, the content and the UIScrollView are all wacky when I dismiss the ViewController. Any help is welcome, this is an awful bug... Thank you!
Test Project:
A simple test can be found here...
http://twostatesaway.com/ModalWithScrollViewTEST.zip
or here
https://drive.google.com/file/d/0B0pG5vRVzBTzdkVzdEtkdmVjdDA/edit?usp=sharing
Screen Shots:
Screen 1: Everything fine. I can show the modal a million times and the content will work as expected after dismissing the modal
Screen 2: Zoom in on content.
Screen 3: When I click the button to presentViewController, the content shifts to the right as the ViewController (in black) is coming up.
Screen 4: Modal is on screen.
Screen 5: When I dismiss the ViewConroller, the content is funny, the bright green view seems to go back to normal, but the button stays in its zoom position, still shifted to the right.
Screen 6: Another funny things is that now I can zoom out more than before. The min zoom is set at 1.0, but now it seems like that is not working.
Try this way...
1) Remove the code from - (IBAction)openModal:(id)sender & make it blank.
2) In story board make the secondViewController class as ModalViewController as below.
3) Drag the line from button to second view & use segue as modal as shown below.
Updated answer
1) clear the viewDidLoad method.
2) Write following code in ViewWillAppear method.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.scrollView.delegate = self;
self.scrollView.minimumZoomScale = 1.0;
self.scrollView.maximumZoomScale = 5.0;
//self.scrollView.contentSize=CGSizeMake(320, 200);
[self.scrollView setZoomScale:self.scrollView.minimumZoomScale];
}
The accepted work around here is to capture the zoom and contentOffset when the modal is coming up, and then set the properties when view is appearing again...
//// Capture values
-(void)viewWillDisappear:(BOOL)animated
{
zoomedScale = self.scrollView.zoomScale;
contentOffsetTemp = self.scrollView.contentOffset;
}
//// This prevents the content from getting messed up (thanks user1673099)
-(void)viewDidDisappear:(BOOL)animated
{
[self.scrollView setZoomScale:self.scrollView.minimumZoomScale];
}
//// Then reassign them values
-(void)viewWillAppear:(BOOL)animated
{
self.scrollView.zoomScale = zoomedScale;
self.scrollView.contentOffset = contentOffsetTemp;
}

UINavigationBar frame animation not possible?

UINavigationBars within a UINavigationController. . . they don't participate in frame animations. Useful, but exactly not what I want right now. Is there a way to turn this off?
I know I could set the showsNagitationBar property to hidden, and add my own to the view, put am looking at possible alterntives.
What I'm Trying to Achieve:
I've put my UINavigationController into a (screen-sized) container view, and want to slide it across to reveal a side menu. . last time that I did this I had custom push/pop methods on the RootVC, and my own navigation bar - worked fine, though a fair amount of boiler-plate code to set up.
This time I've got the same kind of requirement - main content is push/pop based, and some auxiliary VCs that can be revealed from the side. And so for another approach, and considering that this app's look and feel is very standard, I just included a UINavigationController within the RootVC and expected it to work the same.
However the UINavigationBar stays anchored in place, while the rest of the content within the container view moves.
I am not entirely sure what you are trying to achieve, but when using a navigation controller, the entirety of what you see on screen (your top view controller's view PLUS your navigation bar) is rooted in the Navigation Controller's view.
This means that if you do something like:
[UIView animateWithDuration:1.0 animations:^{
CGRect frame = self.navigationController.view.frame;
frame.size.width -= 30;
self.navigationController.view.frame = frame;
}];
You will get your view AND the navigation bar to shrink.
EDIT: You can add/remove the sliding-in views to the navigation controller's view where it is appropriate (for example the nav controller is your root view controller, you could do it in your appdelegate's didFinishLaunch: method). The following code would show an entirely red view sliding in from the left. In your case, this view would be the one from your side view controller.
UIView *left = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
left.backgroundColor = [UIColor redColor];
CGRect ff = left.frame;
ff.origin.x = -ff.size.width;
left.frame = ff;
[self.navigationController.view addSubview:left];
[UIView animateWithDuration:1.0 animations:^{
CGRect frame = self.navigationController.view.frame;
frame.origin.x += 50;
self.navigationController.view.frame = frame;
}];
Is something like this what you were looking for?

Black bar flashes at top of UITableView when pushing to view with "Hides Bottom Bar When Pushed" in IB

This is a weird error that may just be an issue in Xcode for all I know. I have a tab bar controller where the first view is a UITableView with (obviously) a number of cells. When you select a cell, I've set up a segue on the MainStoryboard to go to a detail view controller. I want the tab bar to be hidden when I go to the detail view, so I went into the storyboard, chose my detail view, and clicked "Hides Bottom Bar on Push" in the editor screen that starts with "Simulated Metrics."
Everything works just fine, except that when I tap on a cell, a black bar flashes at the top of the UITableView screen, dropping the tableview cells down (as if the cells are falling down below the tab bar at the bottom), just before the screen pushes over to the detail view. The effect isn't harmful at all, but it's very disconcerting, and I'd like to smooth that out.
The only fix I've found is to uncheck the "Hides Bottom Bar when Pushed" option on the storyboard. That indeed does get rid of that black bar flash, but of course the tab bar stays on the screen when I go to the detail view, which is what I don't want.
Any ideas?
Just for completeness' sake, I went ahead and ran
[self.navigationController setToolbarHidden:YES animated: YES];
on the detail view controller's viewWillAppear method (and even tried it with the storyboard option both on and off), but there was no difference. The toolbar did indeed hide just fine, but I still got that black line at the top. So weird.
I know it is too late !!! I ran into same issue. It seems like the Auto resizing mask for the view was incorrect to be exact the UIViewAutoresizingFlexibleTopMargin. I checked this on in the xib file. If you are trying to do it in code make sure this flag -UIViewAutoresizingFlexibleTopMargin - is not included in the autoresizing mask.
Hope this will help some one in the future
I know it is a bit late, but I have same problem and I can't solve it with any of the previous answers. (I suppose this is the reason non was accepted).
The problem is that view size of the SecondViewController is same as view size of a previous ViewController, so too small to fit in a ViewController with Toolbar hidden. Thats why black background of a UITabBarController is visible at the top when transition is happening, and on a viewDidAppear view will stretch on right size.
For me it help to subclass root UITabBarController and set background color to same background color as SecondViewController has.
class RootViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = Style.backgroundColor
}
}
Then you can leave checkbox checked inside storyboard and it will look ok.
P.S.
If you have some views, that is position on the bottom part of the view, you need to set bottom constraints so they are smaller by 49 (because this is the height of the toolbar), and then on viewDidAppear set the right constraint.
For example:
I have view that need to be position 44 px from bottom edge. Before, I have constraint set to 44 and I have some strange behaviour of that view. It was placed to height and then jump on the right place.
I fix this with setting constraint to -5 (44-49), and then in viewDidAppear set the constraint back to 44. Now I have normal behaviour of that view.
Wow I just had the same issue now, very painful, and no info on the net about it.
Anyway, a simple workaround for me was to change the current view's Frame moving the y coordinates up and making the height bigger by the height of the tab bar. This fixed the problem if done straight after pushing the new view onto the navigation controller. Also, there was no need to fix the Frame afterwards (it must be updated when the view is shown again).
MonoTouch code:
UIViewController viewControllerToPush = new MyViewController();
viewControllerToPush.HidesBottomBarWhenPushed = true; // I had this in the MyViewController's constructor, doesn't make any difference
this.NavigationController.PushViewController(viewControllerToPush, true);
float offset = this.TabBarController.TabBar.Frame.Height;
this.View.Frame = new System.Drawing.RectangleF(0, -offset, this.View.Frame.Width, this.View.Frame.Height + offset);
Objective C code (untested, just a translation of the monotouch code):
UIViewController *viewControllerToPush = [MyViewController new];
viewControllerToPush.hidesBottomBarWhenPushed = YES; viewControllerToPush.hidesBottomBarWhenPushed = YES;
float offset = self.tabBarController.tabBar.frame.size.height; float offset = self.tabBarController.tabBar.frame.size.height;
self.view.frame = CGRectMake(0, -offset, self.view.frame.width, self.view.frame.height + offset); self.view.frame = CGRectMake(0, -offset, self.view.frame.size.width, self.view.frame.size.height + offset);
Do this in viewWillAppear of detailViewController, it should work fine
subclass your navigation controller, or just find the navigation bar
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let backdropEffectView = navigationBar.subviews[0].subviews[0].subviews[0] //_UIBackdropEffectView
let visualEffectView: UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
visualEffectView.frame = backdropEffectView.frame
backdropEffectView.superview?.insertSubview(visualEffectView, aboveSubview: backdropEffectView)
backdropEffectView.removeFromSuperview()
}

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