How to change the width of UITabBarItem? - objective-c

How to change the width of UITabBarItem?
I have an item with the title, that is wider than default item width. How can I fix it?

Solution for iOS7 and greater versions:
A new property has been introduced for UITabBar: itemWidth.
Set the itemWidth to a positive value to be used as the width for tab
bar items when they are positioned as a centered group (as opposed to
filling the tab bar). Default of 0 or values less than 0 will be
interpreted as a system-defined width.
#property(nonatomic) CGFloat itemWidth NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
So you can do this in your AppDelegate:
[[UITabBar appearance] setItemWidth:WIDTH];
If you want to fill the whole UITabBar:
[[UITabBar appearance] setItemWidth:self.window.frame.size.width/NUMBER_OF_ITEMS];

You can change the spacing (and width) of the tab bar items by subclassing UITabBar and overriding its layoutSubviews method. You will find all tab bar buttons in the self.subViews array. Their class is the non-public UITabBarButton but they inherit from UIControl so you can identify all tab bar buttons checking if they are kind of UIControl class. Then all you need is to change the frame of the tab bar buttons.

I just searched through the documentation and saw no method for adjusting the UITabBarItem's width.
A possible solution would be to place a view within the tab bar controller to load a custom UITabBarItem, that is the proper width.

Found easier solution for swift if you subclass the UITabBarController
this will autofill the tab bar items evenly
self.tabBar.itemPositioning = .fill

Swift 5
UITabBar().itemWidth = self.window!.frame.size.width/5

Related

Increase UINavigationBar title font size on scroll

I saw this effect today where the navigation bar title seemingly starts within the view, then shrinks and moves upwards into the navigation bar's title as you scroll the page, it then reverses to its original state when scrolled back to the top.
Does anyone have any insight on how this is done? Is a navigation bar used at all, or is it being mocked using a UIView that shrinks in height and the background colour darkens? Perhaps the title is a label converted to a UIImage and scaled down rather than the font size decreasing?
Just speculating on possible techniques.
Would love to get some opinions on this. Thanks in advance.
Yes, You can change the size of the font and the origin of the Navigation Bar in accordance with your gesture recognizer.
navigationBar.frame.origin.y = -10
will shift the Navigation bar up by 10 points. The font can be changed using
if let font = UIFont(name: "Lato-Light.ttf", size: 34) {
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: font]
}
This format is because using a forced unwrap ! will crash the app with UIFont
In this context, font can be a variable where you call the normal init with same typeface and different size.
These two operations should be performed whenever the gesture recognizer updates its value or scroll position. You may or may not have to redraw the view, however.

Change separator color to background or remove it from NSTableView

I am looking to remove the separator color in View based NSTableView.
It looks like this :
For UITableView there is a method setSeparatorColor: but not for NSTableView.
Solutions will be highly appreciated.
I did this as:
Changed the Intercell spacing to :
[aTableView setIntercellSpacing:NSMakeSize(0, 0)];
And changed the height of the the cell, set view's width to 30.f , the cell being drawn is of 35.f.
Now it is perfect, screen shot :
For NSTableView, Interface Builder has settings for Horizontal Grid, Vertical Grid, and Grid Color. These are reflected in the API as -setGridStyleMask and setGridColor.
They do exactly what you want.
[table setGridColor:[NSColor clearColor]];
[table setGridStyleMask:NSTableViewGridNone];
Answer for Interface Builder :
Maybe I could mention that in view based tables NSTableRowView is responsible for drawing the seperators. So in the inspector for the table you set it the grid to "None" and implement drawSeparatorInRect: in your NSTableRowView subclass, which in your case would mean leaving it empty.

Resized UIToolbar refuses to keep its UIBarButtonItem aligned correctly

I have a UIToolbar at the top of my view, and it needs to be resized in an animation. The toolbar contains:
A UIBarButtonItem using system item UIBarButtonSystemItemAdd (the '+' button)
A UIBarButtonItem using a custom view (the title)
A UIBarButtonItem using the style UIBarButtonItemStyleBordered (the 'Edit' button)
I am adding these buttons using a spacer between each, which keeps the title in the center:
[toolbar setItems: #[addButton, spacer, titleButton, spacer, editButton] animated:NO];
The toolbar resizes just fine, and the two buttons keep their locations pinned to the outside edges. However, the title button does not stay in the center of the toolbar. Instead, it seems to pin its right edge to the same location, creating a space on its left side. During the animation, this give the impression that it is sliding right.
To be clear, I do want the title bar to keep its same width - I do not want it to expand as the toolbar grows. But I need the title to stay in the center of the toolbar.
Since a UIBarButtonItemis not a UIView, I can't (?) use the autoresizingmask functionality.
How do I keep the title in the center of the toolbar?
Additional Info
This might be because the Add and Edit buttons have different widths - when I add only the title (with a spacer either side), the behavior is correct.
It turns out that I was leaving out a crucial detail. I am manually setting the width of the edit button to 50.
If this is removed, the resizing works as expected. However, I am then unable to control the size of the Edit button, which I like to set to 50 so it matches the one on the navigation bar.
I found a workable solution. Keep the width of the Edit button at 50. Add a fixed separator immediately after the '+' button, and set its width to 18 (50 - the width of the '+' button). This balances the items either side of the title.
I know it's too bad, still you can use custom button as bar button item and use images of Add/Edit button in it. So that you can set the button frames, at any places. So your button won't placed to right most place.
UIButton * addButton = [[UIButton alloc] init];
[addButton setBackgroundImage:<AddimageName> forState:UIControlStateNormal];
UIBarButtonItem * addItem = [[UIBarButtonItem alloc] initWithCustomView:addButton];

Rotating UITabBarController Icon

I have an UITabBar in my application. One of the tab bar icons looks like a loading symbol. When the user presses the loading button I want the icon to spin/rotate until the loading is done. Should I use UIImageView to animate or something else? How should I make this happen?
Jacos, unfortunately you cannot do that with the UITabBarController and manipulate the tabBarController's tabBar properties. My best bet would be that you use a UIToolBar and assign a black color and make it appear like a tabBar and have buttons added in them as a subView so that they look like tabBarItems.
Its much more customizable, and you can even provide a scrolling experience and add more buttons to it.
I know this question is 4 years old but I had the same problem and managed to fix it by reading the tutorial in here:
https://medium.com/#werry_paxman/bring-your-uitabbar-to-life-animating-uitabbaritem-images-with-swift-and-coregraphics-d3be75eb8d4d#.bjfpbdnut
The main point is to get the view for desired UITabBarItem and the get the UIImageView from it in viewDidLoad:
UIView *plusView = self.tabBar.subviews[1];
self.plusImageView = plusView.subviews.firstObject;
self.plusImageView.contentMode = UIViewContentModeCenter;
Then in didSelectItem method you can do this:
[UIView animateWithDuration:0.4 animations:^{
[self.plusImageView setTransform:CGAffineTransformMakeRotation(M_PI/4)];
}];
My code only rotate the image view for 45 degrees but you can change as you wish.
I guess you could change the UITabBarItem's icon on a timer, but that seems pretty kludgey. You would have to pre-render each frame of your "loading" icon rather than rotate an ImageView.
Another hackey solution would be to add your ImageView to the UIWindow and move it on top of the TabBarController's TabBar (adding it to the TabBar itself is asking for trouble).
You shouldn't try to animate the actual UIImageView within the UITabBarController. I would take this approach:
Set the image for the relevant tab to nil or a blank image.
Create a UIActivityIndicatorView and add it over the tab bar. Position it over the correct tab.
[self.tabBarController.tabBar addSubview:activityIndicatorView];
When your loading task has completed, restore the normal image to the tab and remove the activityIndicator from the tab bar.

Set vertical scroller style in NSScrollView

How can I set the vertical scroller style in NSScrollView?
If you're using Interface Builder, deselect "automatically hide scrollers". The scroll bars then become visible. Click a scroll bar and edit its control size attributes in the inspector.
If you're doing this in code:
NSScrollView* myScrollView = ...;
[[myScrollView verticalScroller] setControlSize: NSSmallControlSize]; // or whatever
Yes you can set the size in Xcode.
Or rather in Interface Builder:
Make sure to expand the objects panel on the left.
Then you can see two NSScroller objects in the scroll view.
Just select them and set the control size in the Inspector Panel to Small or Mini.