iOS UITabBar items location - ios

Is there any way to create a tab bar in iOS with 3 tab bar items having these positions:
Tab1 - margin left equals 0;
Tab2 - centered horizontally;
Tab3: margin right equals 0 ?
I tried UITabBarItemPositioning.Fill and creating a custom UITabBar in order to find some methods/properties to override, but I didn't find anything useful.

Use TitlePositionAdjustment in UITabBarItem.
You can set the horizontal margin or vertical margin.
Since UITabbarItem is not a UIView , We can't access its subview and can't get the frame from it , so we have to set different fixed values on different devices.
Ugly but it works:
nfloat TitlePositionAdjustment = 0;
if (IPhone4) {
TitlePositionAdjustment = xx;
}
else if (IPhone5)
{
TitlePositionAdjustment = xx;
}
//xxx and so on..
tab.TitlePositionAdjustment = new UIOffset(TitlePositionAdjustment, 0);
If you don't want this solution, I think you need to create custom view to simulate UITabBar.

Related

LeftBarButtonItem with UISearchBar is not visible on iOS 11

The title is pretty self explanatory, on iOS 10.3 using a UIBarButtonItem with a custom view (in this case UIStackView) assigned to a LeftBarButtonItem of a NavigationBar is not visible on iOS 11. I haven't figure out why it is not showed but when I type something with the keyboard my logic of the TextChanged event works! So the UISearchView is there but it is not visible:
Here is some code (It is coded with C# but it is using Objective C methods.):
var width = NavigationController.NavigationBar.Frame.Width;
var height = NavigationController.NavigationBar.Frame.Height;
_searchBarContainer = new UIStackView(new CGRect(0, 0, width * 0.75, height))
{
Alignment = UIStackViewAlignment.Center,
Axis = UILayoutConstraintAxis.Horizontal,
Spacing = 3
};
_uiSearchBar = new UISearchBar
{
BackgroundColor = UIColor.Clear,
BarTintColor = UIColor.Clear,
BackgroundImage = new UIImage(),
Placeholder = Strings.Search
};
_uiSearchBar.SizeToFit();
if (_iOS11)
{
_uiSearchBar.HeightAnchor.ConstraintEqualTo(44).Active = true;
}
_searchbarButtonItem = new UIBarButtonItem(_searchBarContainer);
NavigationItem.SetLeftBarButtonItem(_searchbarButtonItem, true);
ParentViewController.NavigationItem.LeftBarButtonItem = NavigationItem.LeftBarButtonItem;
Using the same code on iOS 10 this works.
Please try out setting up constraints to size properly your _searchBarContainer before setting it as the left bar button item. From iOS11 navigations bars use auto layout. Make sure you only add the constraints if iOS 11 is present, I was having problems in iOS 9 navigation bars otherwise.
Also checkout this thread in the Dev forum where it's explained how the bar items are wrapped inside stack views, maybe also helps with your particular issue.

What is the top bar height of iPhone X?

I would like to know exact height of top bar of iPhone X.
Could you please mention the status bar and navigation bar height of iPhone X.
Please help me.
The display on iPhone X, however, is 145pt taller than a 4.7" display, resulting in roughly 20% additional vertical space for content.
for more information you get HIG for iphone X from apple documents and detail description in here1 and here2
status bar height
previously 20pt, now 44pt
Because of the sensors on top of the display, the new status bar is split in 2 parts. If your UI is doing something special with that space (previously 20pt high, now 44pt), because it will be taller on the iPhone X. Make sure that it can be dynamically changed in height. A great thing is that the height won’t be changed if a user makes a phone call or is using a navigation app, which was previously the case on other iPhones.
portrait
Navigation bar height as normal 88 and large title time 140
Standard title - 44pt (88pt with Status Bar)
Large title - 140pt
bottom bar - 34pt
Landscape
Standard title - 32pt
bottom bar - 21pt
Nav bar is 44pt as usual (when no large titles) and the status bar has increased from 20pt to 44pt. Here's what you can type in the debugger to verify it:
You can programmatically obtain the navigation bar's height by using safeAreaInsets on the view in the contained view controller:
let navBarHeight = view.safeAreaInsets.top
This will account for whether it's a large title navigation bar or not, and whether or not there's a search bar attached to it.
See the safeAreaInsets documentation for more information.
You can simply get it in the next way (Swift 3):
let barHeight = navigationController?.navigationBar.frame.maxY
To get correct value make sure that you call it after setting prefersLargeTitles
navigationController?.navigationBar.prefersLargeTitles = false
You can use the navigation bar's .frame property to figure out the overall height of the top bar area:
Swift 5.0:
let xBarHeight = (self.navigationController?.navigationBar.frame.size.height ?? 0.0) + (self.navigationController?.navigationBar.frame.origin.y ?? 0.0)
ObjC:
CGRect navbarFrame = self.navigationController.navigationBar.frame;
float topWidth = navbarFrame.size.width;
float topHeight = navbarFrame.size.height + navbarFrame.origin.y;
I suppose this is a bit of a cheat, but adding the navbar's height with its y origin seems to give the correct total height regardless of device.
There is no specification in Apple Docs
Apple Docs
According to Geoff Hackworth its 88
Navigation title types :
Standard title
Large title
Increasing navigation bar in iOS 11
navigationController?.navigationBar.prefersLargeTitles = true
If you're using a UIWindow and you need to know the top bar height you can use this:
// old way of getting keyWindow
//guard let keyWindow = UIApplication.shared.keyWindow else { return }
// new way of getting keyWindow
guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return }
let navBarHeight = keyWindow.safeAreaInsets.top
print("navBarHeight:" , navBarHeight)
I got the idea from #Paolo's answer
Use it if you want to know where need start content
extension UIViewController {
var navigationBarbarContentStart: CGFloat {
return self.navigationBarTopOffset + self.navigationBarHeight
}
var navigationBarTopOffset: CGFloat {
return self.navigationController?.navigationBar.frame.origin.y ?? 0
}
var navigationBarHeight: CGFloat {
return self.navigationController?.navigationBar.frame.height ?? 0
}
}

Adjust UIView width when other views increase or decrease in size

I have a UIView with a side menu that comes from the left and pushes the right view from full with to a smaller size (full width - (menu width)).
Per someones suggestion I accomplish that effect by changing the constant in the constraint for the menu width: from 0 to 200.
The (right side view) UIView that's gonna hold the view that I will load to it has the constraints seen in this image (menu is on the left in blue):
I add the new UIView to the detailsView (container mentioned above) with the following code:
var viewNames = NSDictionary.FromObjectsAndKeys (new NSObject[] {
view.View
}, new NSObject[] {
new NSString ("detailsView")
});
detailsViewContainer.AddSubview (view.View);
view.View.TranslatesAutoresizingMaskIntoConstraints = false;
detailsViewContainer.AddConstraints (NSLayoutConstraint.FromVisualFormat ("H:|[detailsView]|", 0, new NSDictionary (), viewNames));
The problem is that the newly added view always has the full width (1024) when the menu is collapsed but also when the menu is expanded, pushing the view outside the app limits on the right.
Any help would be appreciated.
Thanks in advance!
Make the master view width constraint (add one if there is no) to be <= 1024 (not strict). I would do the following:
|H:|-0-menuView-masterView-0-|
and specify in designer the width constraint for masterView as Less or Equal 1024
and specify in designer the width constraint for menuView as equal to 200. Make an outlet for it and change dynamically in code with
animation from 200 to 0 and back when required.
where:
menuView is menu UIView
masterView is master UIView placeholder
when your menu (green view) is open width constraint will be equal 200:
as soon as you set constraint to 0 your view will resize the main placeholder (orange view) as well:
Please find storyboard sample by the following link:
https://dl.dropboxusercontent.com/u/19503836/Main.storyboard

IOS:UITabbar item click again and again it is reducing the UITabbar button item size in IOS 7

I'm took the Tabbar viewcontroller in this ,I added the 5 item and .I given the image insects is (24,0,0,6).
All button images are added in xib [under the Bar item -->image]Please help.
Thanks.
Adding to a similar answer here:
iOS Tab Bar icons keep getting larger
Not sure if this is an iOS7 bug but I've noticed that image insets need to be balanced.
You have specified insets for top and right but:
if you set a top inset, in order to balance it, you need to set the negative of it to the bottom inset
if you set a right inset, in order to balance it, you need to set the negative of it to the left inset
So, instead of having image insets like (24,0,0,6), use balanced image insets such as UIEdgeInsetsMake(24,-6,-24,6)
Doing so should protect your tabBarItem image from getting whacked on every tap.
If this doesn't suit your requirements, then redesign your tabBarItem image so you can have balance insets or... no insets at all.
Here's the workaround for a bug I've encountered with UITabBarController's UITabBar. If I tap a UITabBarItem once after it's selected, the icon shrinks. What I'd like to do is disable touches. UITabBarItem only has a setting for isEnabled, which grays it out if I set it to false...not what I was looking for.
I used a derivative of this answer to figure it out. With a UITabBarController with 3 tabs, printing tabBarController.subviews, I saw 3 UITabBarButtons and a UIBarBackground. The origin of UIBarBackground's frame was always (0, 0), putting it at the front of the sorted array, so I really don't need to know what the subview is, just "where it is" and whether it will always be there. The UIBarBackground is always going to be at the front of an array of tabBarController.subviews sorted by frame.minX, so I just need to remove it from the front.
Solution
Here's what the extension looks like:
extension UITabBarController {
var buttonViews: [UIView] {
var tabBarButtons = tabBar.subviews.sorted(by: {$0.frame.minX < $1.frame.minX})
tabBarButtons.removeFirst()
return tabBarButtons
}
}
I also created a struct in my Constants file, so I don't have to remember tab names:
struct TabBarItem {
static let firstTab = 0
static let secondTab = 1
static let thirdTab = 2
}
...and finally, where to use it:
In viewDidAppear (NOT viewDidLoad), add the following line to disable the UITabBarItem that you don't want to disable, but not gray out:
tabBarController?.buttonViews[TabBarItem.firstTab].isUserInteractionEnabled = false
In viewWillDisappear, re-enable the tab, as follows:
tabBarController?.buttonViews[TabBarItem.firstTab].isUserInteractionEnabled = true

How do I move FPPopover as low as I want? If I push it too low, it jumps back to the top

I'm using FPPopover to present a pop over view for my iPhone app. I'm having an issue, however, where when I present it, it will only allow me to present it so low or it will jump to the top. And this is well before it gets cut off anyway.
For example:
[self.speedOptionsPopover presentPopoverFromPoint:CGPointMake(0, 235)];
Works fine, but if I put it a 255 instead of 235 (as it's a good 40px from the bottom) it jumps back up to the top.
Does anyone have any experience with this or how I could fix it?
Also, bonus points if you can explain why the content for the popover always starts like 50px from the top, when I want it to start up higher. How can I change this also?
More code from the creation:
- (void)speedOptionsTapped:(UIBarButtonItem *)sender {
// Set the delegate in the controller that acts as the popover's view to be self so that the controls on the popover can manipulate the WPM and number of words shown
self.speedOptionsController.delegate = self;
self.speedOptionsPopover.arrowDirection = FPPopoverNoArrow;
self.speedOptionsPopover.border = NO;
self.speedOptionsPopover.contentSize = CGSizeMake(320, 190);
[self.speedOptionsPopover presentPopoverFromPoint:CGPointMake(0, 235)];
}
Try replacing this part of the code in FPPopoverController.m:
//ok, will be vertical
if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown)
with this code:
//ok, will be vertical
if (self.arrowDirection == FPPopoverNoArrow)
{
r.origin.x = p.x;
r.origin.y = p.y;
}
else if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown)
The reason you might be having this issue is that the macro FPPopoverArrowDirectionIsVertical considers a popover with no arrows as having a vertical arrow. So, the result is that is tries to best position your popover as close as possible to the view that triggered the popover.
If you replace the code as indicated above, you'll be creating a special case for popovers with no arrows and asking that the original points be respected without repositioning.

Resources