Hide UITabBar in UITabBarController with autolayout - cocoa-touch

I'm trying to hide the tab bar from within a UITabBarController.
This successfully hides the tab bar:
self.tabBar.hidden = true
However, I now have a black "blank spot" where the tab bar used to be.
I've seen some solutions to this problem on SO, but they modified the frames directly, and didn't take into autolayout.
How can I stretch the main view to fill the rest of the screen, with autolayout?

Often times its because, the controllers view is not allowed to extend under the bottom bar. You can enable this by
self.edgesForExtendedLayout = UIRectEdgeBottom;

The viewcontroller in which you wish to hide the tabbar should override the variable:
override var hidesBottomBarWhenPushed: Bool {
get {
return navigationController?.topViewController == self
}
set {
super.hidesBottomBarWhenPushed = newValue
}
}
It will take care of your bottom autolayouts too and adjusts the empty space in bottom as well.

Related

How to get inputAccessoryView to anchor above the UITabBar?

I'm trying to figure out the best way to have a custom inputAccessoryView rest on top of a tab bar. Currently, I have an inputAccessoryView that rests at the very bottom of the screen, but it covers the tab bar. Any one know the best practice for shifting that inputAccessoryView up?
Currently I have a view defined in a storyboard with a tab bar. Its corresponding view controller takes the view and calls becomeFirstResponder. I've overwritten both:
- (UIView *)inputAccessoryView and -(BOOL)canBecomeFirstResponder
within the view's .m
Found a workaround by shifting toolbar frame by bottomSpacing = tabbar height:
- (void) layoutSubviews {
[super layoutSubviews];
CGRect origFrame = self.frame;
origFrame.origin.y = _keyboardIsVisible ? 0 : -self.bottomSpacing;
self.frame = origFrame;
}
Strangely it works well in JSQMessagesInputToolbar, but it's lost after animations if I do this in UIView that wraps toolbar, or maybe I'm missing something..

iOS 8 - Modal in Popover

I have a popover with TabBarController in it. In one tab there is a TableViewController with a list of names. And there is a plus button, that has a modal segue to AddCharacterVC for adding new names.
In iOS 7 I do it like this:
AddCharacterViewController *acvc = (AddCharacterViewController *)segue.destinationViewController;
acvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
acvc.modalPresentationStyle = UIModalPresentationCurrentContext;// so it does not take full screen in popover
And in AddCharacterVC I set content size like this:
- (void)viewWillAppear:(BOOL)animated {
CGSize size = CGSizeMake(320, 480); // size of view in popover
if (IDIOM == IPAD && [self respondsToSelector:#selector(preferredContentSize)]){
self.preferredContentSize = size;
}
And it works perfectly.
However, in iOS 8 modal view does not cover the whole popover, leaving TabBar visible. The user can tap on it or not, anyway modal view won't unwind properly.
I've tried:
setting acvc.modalPresentationStyle to UIModalPresentationOverCurrentContext
tried to set TabBar hidden
checked in storyboard that edges of TableVC extend under Bottom Bar and Bottom Bar in Modal View (AddCharacterVC) is set to none
All with no results.
Now the only thing I can think of is to try making modalPresentationStyleCustom and use UIPresentationController (I'm trying to do it now, but I haven't done it before). Am I missing something? Could there be other way to do it? Sorry, I cannot post images here yet. Many thanks in advance!
Ok, so I've set the modalPresentationStile to UIModalPresentationCustom, and used UIPresentationController - I've just copied code from WWDC-14's LookInside project and modified it a bit.
I'm not sure if it was the best solution, but it worked in my case.

Custom UIControl with UILabel dimming on tint color change

In case of UISegmentedControl, once a popover or alert is present, the Control dims to grey (desaturates the tint color)
I'am building my own UIControl subclass, which uses a UILabel as a subview
i want to dim (desaturate) the text color of the UILabel, same way as by UISegmentedControl or (UIButton...)
Look at the tintColor and tintAdjustmentMode properties on UIView (available since iOS 7) and the tintColorDidChange method.
If you override them in your custom view you can respond to being dimmed out.
As the iOS 7 UI Transitioning Guide says:
When an alert or action sheet appears, iOS 7 automatically dims the tint color of the views behind it. To respond to this color change, a custom view subclass that uses tintColor in its rendering should override tintColorDidChange to refresh the rendering when appropriate.
The solution may look like this :
- (void)tintColorDidChange {
self.titleLabel.textColor = self.tintColor;
}
While the accepted answer did help me, the result was that the dimmed color was applied to my control even when the screen was not dimmed. I fixed this in the following manner:
override func tintColorDidChange() {
switch tintAdjustmentMode {
case .Dimmed:
myLabel.textColor = UIColor.grayColor()
default:
myLabel.textColor = UIColor.blueColor()
}
}
This correctly applies a gray color to the control only if the screen is dimmed.

Hiding Nav Bar moves view "up"

The usual story -- I'm making an iOS 5/6 app run under iOS 7 and the navigation bar behavior change is causing a problem.
The app already worked like the iOS 7 default with a full-screen view and a translucent nav bar "over" of the view. The problem is that hiding/un-hiding the nav bar causes different behavior in iOS 7. On iOS 5/6 hiding/un-hiding the nav bar does not change the view. On iOS 7, hiding the bar visually moves the view up leaving a blank bar at the bottom of the screen and un-hiding the bar moves the view back down to occupy the full screen (with the nav bar on top, of course).
I need to continue to support iOS 5 so I don't use auto layout, but I do use the full screen.
I have a view in which I'm viewing a zoomable image -- so the view controller has a fullscreen view containing a scrollView which contains an imageView.
The status bar is always hidden.
I get to the view controller via a navigation controller so there is a (black, translucent) navigation bar which lies over the top of my fullscreen view/scrollView/imageView.
After a brief delay some overlaying labels fade and the navigation bar is hidden
A single tap restores the overlay labels and un-hides the navigation bar.
This works on iOS 5/6 -- the navigation bar slides off the top of the screen uncovering the top of the view/image.
On iOS 7, when the navigation bar slides off the top of the screen the entire view visually moves up a corresponding amount (i.e. 44 points) leaving a black bar at the bottom of the screen. I can see this by setting a background color on the top-level view and resizing the scrollview enough to see the background; the top of the view does indeed move offscreen and the background color is not drawn over the bottom (44 points) of the screen.
BUT, self.view.frame doesn't change and remains at {0, 0} 320 x height.
When I single-tap to restore the overlay info and navigation bar the view moves back down to occupy the full screen and the translucent nav bar is over the top of the view/image.
Nothing I've tried changes the behavior:
Changing the IB view controller layout controls (Under top bars, Under bottom bars, Adjust scroll view insets). Building for 5.1, 6.1, and 7.0 all produce the same result when run under 7.0.
self.edgesForExtendedLayout = UIRectEdgeNone
does nothing. Using the layout delta values doesn't do anything. In IB the view looks the same when "viewed as" iOS 7 and iOS 6 and earlier. I print out a lot of debug info but nothing about the view (or scroll view) seems to change when the view moves "off screen".
The code that shows the overlay info (run when the view is first shown and on single-taps) is:
- (void) showOverlayInfo {
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
[[[self navigationController] navigationBar] setTranslucent:YES];
[[self navigationController] setNavigationBarHidden:NO animated:NO];
overlayInfoHidden = NO;
overlayInfoFading = NO;
self.infoButton.hidden = NO;
self.infoButton.alpha = 1;
self.descriptionLabel.hidden = NO;
self.descriptionLabel.alpha = 1;
}
The code that hides the overlay info is:
- (void) hideOverlayInfo {
overlayInfoHidden = YES;
overlayInfoFading = NO;
self.infoButton.hidden = YES;
self.descriptionLabel.hidden = YES;
[[self navigationController] setNavigationBarHidden:YES animated:YES];
}
So can anybody tell me what (presumably simple) thing I'm missing?
I finally found my problem.
The key fact is that the image-viewer view controller was in a UIPageViewController,
so what I was looking at and experimenting with was really "inside" another view controller.
Although I had disabled the view controller setting Adjust Scroll View Insets for the image viewer VC, I hadn't done it for the containing VC that created the UIPageViewController and the UIPageViewController presents the pages in some subclass of a UIScrollView. When I changed them for the parent VC, the problem vanished.
So I think the moral of the story is to:
Think about the problem more globally when local doesn't work because maybe you're missing some important context.
If you don't want to use the iOS 7 behavior, change the settings for every single view controller you have!

UIPopoverController shifting with UINavigationController view pushing

I am using a UINavigationController within a UIPopoverController and pushing between three views within that navigation controller.
The first two views are the same width (320.0f) but the third view is the maximum 600.0f. I run into a very specific issue with things resizing coming back from the widest view. If I hit the back button the animation back to the smaller width forces the popover controller to animate to the left shifting the alignment away from the barbuttonitem the popover was originally presented from. How can I keep that popover controller glued to the right instead of always resizing off of the left most bound? Could there be an alignment type of flag on the navigation controller? Could it be something on the ViewWillDisappear on the widest view?
Here is the ViewWillAppear for the two smaller view controllers:
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
SizeF vcSize = new SizeF(320.0f, 365.0f);
ContentSizeForViewInPopover = vcSize;
NavigationController.ContentSizeForViewInPopover = vcSize;
}
And here is the ViewWillAppear for the larger view controller:
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
SizeF vcSize = new SizeF(600.0f, 700.0f);
ContentSizeForViewInPopover = vcSize;
NavigationController.ContentSizeForViewInPopover = vcSize;
}
Any help... as always, is greatly appreciated.