Maximize Size of UITabBarItem image - ios

I would like to create a custom UITabBarItem with a Icon-image thats size is a little bit bigger than usual. The thing is I don't want to use a full replace of the background image because i would like to have the translucent effect of the TabBar.
So i would like to know 2 things:
What sizes are now correct for the new iOS7 UITabBarItems and their icons
How do I modify the size of the icon to display a bigger icon, because i dont want to show a title. Without the title its kinda small. In mind to keep the translucent effect displaying.
Any help or suggestions would be great!

Regardless of the icon’s visual style, create a toolbar or navigation bar icon in the following sizes:
About 44 x 44 pixels
About 22 x 22 pixels (standard resolution)
Regardless of the icon’s visual style, create a tab bar icon in the following sizes:
About 50 x 50 pixels (96 x 64 pixels maximum)
About 25 x 25 pixels (48 x 32 pixels maximum) for standard resolution
Have a look at these Developers guide for bar & buttons
Bar icons in Human interface guidelines

To increase the size, try below code,
NSArray *items = self.tabBarController.tabBar.items;
for (UITabBarItem *b in items)
b.imageInsets = UIEdgeInsetsMake(-5, -5, -5, -5);
If you want to decrease, try passing positive values to UIEdgeInsetsMake(top,left,bottom,right)

Swift 4.2,
let array = tabBarController?.tabBar.items
for controller in array! {
controller.tabBarItem.imageInsets = UIEdgeInsets(top: 5, left: -5, bottom: -5, right: -5)
}

Related

How to center a SF Symbols image vertically in UITabBarItem?

I am using SF Symbols images as tab images in my iOS app by assigning them as follows:
self.tabBarItem.image = UIImage(systemName: "ellipsis")
This results in all images being top-aligned, but I would like to have them centered vertically.
What do I have to do for this?
Apparently SF symbols are rendered with system font size by default. So if you add a baseline offset of half that size to the ellipsis symbol you could almost perfectly center it vertically that way.
It's only almost perfect because ellipsis symbol has a height of its own which is not accounted for by this solution, even if it is not much.
self.tabBarItem.image = UIImage(systemName: "ellipsis")!.withBaselineOffset(fromBottom: UIFont.systemFontSize / 2)
The best solution, which will make your button identical to "tabBarSystemItem: .more", but with the possibility of removing the title and applying Configuration is the following:
self.tabBarItem.image = UIImage(systemName: "ellipsis", withConfiguration:
UIImage.SymbolConfiguration(weight: .black))!.imageWithoutBaseline()
You have to set the image insets on the UITabBarItem to shift your icons down 6 or 7px (depending on your icon size).
In code:
I've done this by creating a subclass of UITabBarController and adding this code to the bottom of my viewDidLoad method:
tabBar.items?.forEach({
$0.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
})
(You could also do this in your ViewController classes, if that's where you configure each of their tab bar items.)
In storyboards:
You can also do it using storyboards by selecting your TabBarItem in the storyboard and adjusting the insets in the info panel:

UITabBarItem - Position image separately from title text

I have a UITabBar with 5 UITabBarItems, each containing an image and a title. Currently, the images are positioned centered above the title text. When an item is selected I bold the text, however this causes the positioning of the image to change slightly since the text now takes up more space. How can I divorce the positioning of these two elements in a UITabBarItem?
Try adjusting the image insets to get your desired look.
For example, you could try:
tabBarItem.imageInsets = UIEdgeInsets(top: -1, left: 0, bottom: 1, right: 0)

Xamarin - Button with text and image in absolute layout results in mis-aligned elements

I am trying to create a button in a Xamarin Forms cross-platform app (iOS and Android), where the button has both text and an image. The XAML is pretty straightforward:
<AbsoluteLayout ...>
<Labels and backgrounds and such>
<Button x:Name="HomeButton2" TranslationX="6" TranslationY="100"
BackgroundColor="#efeff4" TextColor="#4a4a4a"
WidthRequest="58" HeightRequest="76"
ContentLayout="Top,5"
Image="TaskBar_Assets_HomeButtonIcon.png" Text="Home"
Clicked="HomeButton_Clicked" />
</AbsoluteLayout>
but what I get on the iPad is a button where both the image and the text are strangely pushed over to the side:
(the source image "TaskBar_Assets_HomeButtonIcon.png" is 47 x 44 so it should fit fine in the overall button area)
The only way I can find to make this look better, is to make a custom control based on Button, and then I can see that several of the properties of the underlying UIButton seem wonky:
The Control.ImageView.Frame is all zeroes:
Control.ImageView = <UIImageView: 0x12df52940; frame = (0 0; 0 0);
clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO;
layer = <CALayer: 0x173623180>>
The Control.ImageEdgeInsets and .TitleEdgeInsets look odd (the right + left seem like they leave no space for the image or text):
Control.ImageEdgeInsets = {-8.9501953125, 20.33935546875, 8.9501953125, -20.33935546875}
Control.TitleEdgeInsets = {22, -23.5, -22, 23.5}
What I'm doing, is adjusting the Control.ImageEdgeInsets so that Control.ImageEdgeInsets.Left is equal to the half of the (button width minus the image width) and setting Control.ImageEdgeInsets.Right to zero (for no particular reason except that it works)
and then figuring out what to set Control.TitleEdgeInsets was done with trial & error, I ended up with values related to the width of the "Home" text (41 pixels):
Control.ImageEdgeInsets updated to {-8.9501953125, 5.5, 8.9501953125, 0}
Control.TitleEdgeInsets updated to {22, -50, -22, -9}
That results in a reasonable button look:
although it looks like I need to do more trial & error to get the text "Home" actually centered.
But why do I need to go through all this? Why doesn't the button just display text & image correctly in the first place?
And if I do have to go through all this, why are the values for Left & Right for ImageEdgeInsets and TitleEdgeInsets so different?
Most of the articles I have read about images on buttons suggest constructing your own using an Image and a Label in a grid using a gesture recognizer to handle the tap.
You could also try a button and an image in a grid.
Use Margin to adjust placement.
I try and stay clear of absolute layout.
Here's the ButtonRenderer source code from Xamarin.Froms.If you set the ContentLayout to Top, the below codes will be run:
void ComputeEdgeInsets(UIButton button, Button.ButtonContentLayout layout)
{
...
var horizontalImageOffset = labelWidth / 2;
var horizontalTitleOffset = imageWidth / 2;
...
button.ImageEdgeInsets = new UIEdgeInsets(-imageVertOffset, horizontalImageOffset, imageVertOffset, -horizontalImageOffset);
button.TitleEdgeInsets = new UIEdgeInsets(titleVertOffset, -horizontalTitleOffset, -titleVertOffset, horizontalTitleOffset);
}
As the codes show, the Left offset of image is horizontalImageOffset which is labelWidth / 2. The Left offset of title is horizontalTitleOffset which is imageWidth / 2.
So, when the text is wider, the left offset of image will be bigger. When the image is wider, the left offset of text will be bigger.
Edit:
In native iOS, the default layout is like the left image: Image is at left and Label is at right. In Xamarin for Top setting, Xamarin moves the Image up and right, moves the Label down and left to makes them like the right image. I paint this illustration, hope it clear.

Swift: programmatically align labels for different IOS screen sizes

I'm new to Swift and ios development. I have 6 labels and a horizontal SKScene in my App. I would like to align those 6 labels beautifully and automatically. Now I have fixed the positions and the alignment always looks awful on some screen size while good on other.
I have not used storyboards or other graphical editors for building the ui but everything is done in code. Therefore I'm looking for a programmatic solution (code examples) for handling the alignment.
If you want to place them in the middle of the screen horizontally, but give them different y positions, you could just do something like this for each label:
label.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame) * 0.80)
To place them at different y positions, just multiply by the maxY by a different decimal number. This way, all of the labels are aligned along the x-axis and appear at different y-positions, like a column and they will appear this way on every screen size because they are positioned relative to the screen size and not in a fixed position.
You can align the labels (lets say at the center of the screen) like this.
var label1 = UILabel(CGRectMake: 0, 0, 200, 40)
label1.center = CGPointMake(UIScreen.mainScreen().bounds.size.width/2, 30)
var label2 = UILabel(CGRectMake: 0, 0, 200, 40)
label2.center = CGPointMake(UIScreen.mainScreen().bounds.size.width/2, label1.center.y + 30)
and so on. Just reference the main screen bounds and not static points for alignment, so that they are centered in any screen size.
What I ended up doing was to create an empty SKSprite to which I included the SKLabels. Now I can control by the pixed the distances between labels but align the top-level sprite in the middle of the screen despite screen size.

Extend image repeating horizontal line and repeating vertical line on iOS

I have image and in that image i want to repeat horizontal and vertical line, so i extend my image.
For example i have image 50X50, and i want it to be 50x70, by repeating line x = 15. Is this even possible on iOS?
EDIT:
Ok i'll try to be more clear. I have image 60x60, which is rectangle basically, with width 60 and height 60. Now i want to streach that image to be 80x60, by repeating pixles with x = 40. Or to draw it simply, i have:
123456
1 XXXAXX
2 XXXAXX
3 XXXAXX
4 XXXAXX
5 XXXAXX
6 XXXAXX
and i want it to be:
12345678
1 XXXAAAXX
2 XXXAAAXX
3 XXXAAAXX
4 XXXAAAXX
5 XXXAAAXX
6 XXXAAAXX
I repeat all pixels on image that are on the line 40. And i want to do it on any number of images.
The key to achieving your desired result is resizableImageWithCapInsets: on UIImage. For example, take the following 50px by 50px image (Note: this is the #2x version):
If you want to stretch the red line horizontal, you first define a UIEdgeInset that describes the position of the red line:
UIEdgeInsets redLine = UIEdgeInsetsMake(0, 15, 0, 34);
This defines a one-pixel wide slice of the image offset by 15px from the left. The right offset is 34 because the right edge of the stretchable slice is at 16px and 50 (image width) minus 16 is 34.
Now that we have the UIEdgeInset, we can load the image and create a stretchable version of it:
UIImage *stretchableImage = [[UIImage imageNamed:#"my_image"] resizableImageWithCapInsets:redLine];
We can assign this stretchableImage to a UIImageView with the frame that we need:
UIImageView *stretchedImageView = [[UIImageView alloc] initWithImage:stretchableImage];
stretchedImageView.frame = CGRectMake(100,100,70,50); // The image view is 70px wide
In the app, stretchedImageView will look like this:
There's another method called resizableImageWithCapInsets:resizingMode: that allows you to tile the image slice rather than stretch it, so you can do crazy things like take this image:
And tile it horizontally like this:
If i understand the question correctly, you should use:
(UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
UIEdgeInsets is structure that specifies float values for each cap
inset: top, left, bottom and right areas of an image. To apply this to
the image for the button, here is all we need to do:
UIImage *buttonImage = [[UIImage imageNamed:#"blueButton"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 16, 0, 16)];
This requests that the left and right 16 pixels of the original image
are not scaled or resized when stretching the image to accomodate the
button size frame defined above. The end
OBS: This only work well for plain images, for example images with gradient will not work well.
Take a look here for more detail.
Just repeat an image in UIImageView like this:
var dottedLineView : UIImageView = {
let view = UIImageView()
view.contentMode = .scaleAspectFill
view.clipsToBounds = true
view.backgroundColor = UIColor(patternImage: #imageLiteral(resourceName: "dashedLine"))
return view
}()

Resources