What effects does iOS add to UIBarButtonItem images? I want to put three of my "buttons" in a UISegmentControl segment to visually group them. However, UISegmentControl does not add the same effects that UIBarButtonItem does.
There seems to be a black shadow just above the image in the UIBarButtonItem, but I haven't been able to match it through experimentation.
I don't mind doing this in code or in a graphic editor, though I'd prefer code. :)
Apple's docs say this, which I assume is the same basic approach:
Toolbar images that represent normal and highlighted states of an item derive from the image you set using the inherited image property from the UIBarItem class. For example, the image is converted to white and then bevelled by adding a shadow for the normal state.
My main concern is matching the shadow; the base colour is not black, and I don't know the opacity.
Related
I need to have a circular UIButton that draws a custom color in the middle, along with an outer ring that is drawn as the default tint color (similar to a UIColorWell).
I've tried a few different approaches:
Using a multicolor SFSymbol: This would be an elegant solution, but as far as I can tell there's no way to apply the tint color to just a part of the image while setting the center to be a custom color. Either the entire image is tinted, or the image is drawn as the default colors set in the symbol file. Also, I need to support iOS 14, while the new hierarchical options that may allow me to accomplish this were added to iOS 15.
Setting various layer properties (ie, cornerRadius, borderColor, etc): This works and may be a decent fallback solution, but I'm unable to get the look that I'm going for (namely, having a transparent ring between the outer border and inner colored circle).
If there's a way to use either of the above options, please educate me! Either one seems like a better solution than:
Overloading the draw function: This is the option I'm going with at the moment, as it allows me to have complete creative control over the look of the button. The rest of this post will be regarding this method.
So far I was able to get the button to be drawn exactly as I wanted. However, I am unable to figure out how to draw the button appropriately with regards to various state changes.
For example, if a popover is displayed, all of the normal buttons are automatically redrawn as disabled. My custom button, however, isn't redrawn so I am unable to respond to the state change.
Same thing with tapping on the button - normal buttons are briefly shown in an emphasized color but my custom button doesn't respond.
Does someone have an example as to how to support overriding UIButton drawing with various states?
I was able to get the desired behavior by overriding tintColorDidChange in order to trigger a redraw of the button. Now I am able to draw the outer ring in the correct color (including grayed out when a popover is displayed) while maintaining the desired inner color.
I'm wondering what would be the best way to desaturate a UIView—particularly, a UISliderView with custom appearance applied to it. In iOS 7, the standard controls fade out their tint colors when another view appears over them (for example, a share sheet or UIAlertView), but since mine is built from UIImages, the tint property doesn't apply to it, and they remain saturated.
Is there a good, easy way to desaturate this, short of re-applying a new UIAppearance for it? (If I were to go that route, would I even be able to animate the transition from colored images to greyscale ones?)
Thanks in advance!
I am trying to achieve this look for my back button:
But no matter where I sample the shade of green in photoshop, it never comes out correct. For example:
Any suggestions on how I can achieve the exact same look?
The tint color is exactly that—a tint. iOS uses that color as a base to create a nice-looking button in the style of normal navigation bars.
If you want to control your button's appearance more precisely than tinting allows, your best bet is to create a set of images and use -setBackButtonBackgroundImage:forState:barMetrics: to use them. If you want this look for all bar button items in your app, use that method on +[UIBarButtonItem appearance], rather than a specific bar button item.
In order to produce the BackBarButtonItem's gradient, iOS does the following:
Applies the tint color that you specify
Applies a transparent overlay on top of the back button
Here are the retina-display overlays it uses for iPhone (these were obtained using UIKit-Artwork-Extractor):
Default Back Button Overlay
Pressed Back Button Overalay
Unfortunately, there is no way to tell iOS / UIBarButtonItem NOT to render these overlays on the back button (thereby, this gives the default navigation bar and buttons a pretty consistent look across all apps).
If you don't want to have this overlay applied (it will darken the button in both states), you have to create your own back button images - for the default and pressed states, portrait and landscape orientations, and retina and non-retina displays (8 total images).
As Brent Royal-Gordon mentions in his answer, you can apply these images using the appearance proxy for UIBarButtonItem to have them used throughout the app. In example, you'd set the default background image state like this for portrait orientation:
UIImage *defaultBackImage = [UIImage imageNamed:#"My-Default-Back-Button"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:defaultBackImage forState: UIControlStateNormal barMetrics:UIBarMetricsDefault];
It looks like the button is adding another semi-transparent gray layer over the button. I can't check right now but I would look for settings to disable the semi-transparent layer effect or try different button style/states.
for a button I see 2 fields: background image and image. Is the only difference that a background image allows for text on top of it?
These images serve different purposes.
The backgroundImage is the graphical representation of the button. This image typically represents the different possible states of the button (normal, selected, highlighted) and is usually stretchable (horizontally and/or vertically) to be usable with varied button sizes.
The image is content that sits within the button and is the graphical analogy to the text property.
A common usage pattern would be to use the same backgroundImage for multiple buttons in your app for a consistent theme but to use different images depending on the contextual meaning of each button.
Also, backgroundImage is not used for layout calculations. For example, [myButton sizeToFit] will take into account the image but not the backgroundImage.
Yes, it's the only difference I know
I'm trying to change the appearance of my UIButtons int the view as well as UIBarButtonItems in the NaviBar or toolBar or SegControl.
And here are 2 questions.
NO.1. How can I set customed background pictures to the buttons I mentioned while I can change their titles programmaticly? I mean I found that if I set the background of a button, the title seems to be concealed by the background image?
NO.2. I tried to add the text of the title directly on the png, ( which is actually a imperfect way since I need to change the title during the runtime). Anyway it works out both the image and the text, but the resolution seems to be reduced because the text became sort of blurred.
Can anyone give me some advices how to achieve it? Thanks a lot!
NO.1 The button title should not be obscured by the background image. Are you setting the button's image in code like this:
[btn setBackgroundImage:image forState:UIControlStateNormal];
? You may be instead setting the button's image property (which is different from its background image).
NO.2 You really don't want to be adding text to the button PNG, for the exact reason you mention. Buttons in iOS are designed to display images and text the way you want - put your energy into getting the built-in buttons working the way they should. There are umpteen billion tutorials out there about how to do this.