How to set UIBackgroundConfiguration for UIButton? - ios

I am struggling to change background properties of UIButton.
They can be easily modified using "Background Configuration" settings in Interface Builder:
but I don't understand how to set them programmatically.
For example, I try to do it like this:
UIBackgroundConfiguration * config = [UIBackgroundConfiguration listPlainCellConfiguration];
[config setStrokeColor: UIColor.labelColor];
but where should I assign this 'config' value? There is nothing like 'button.backgroundConfiguration' property or anything similar for UIButton object.
Note:
'configuration' property of UIButton object is not available in code (Objective C, Mac Catalyst, iOS 15) despite documentation statement, screenshot attached. Will be great to know the reason why this is so.

The background configuration is part of the UIButtonConfiguration (the button's configuration).
https://developer.apple.com/documentation/uikit/uibuttonconfiguration/3750780-background?language=objc
Here's an example of configuring a button created in the storyboard:
UIButtonConfiguration * con = self.button.configuration;
[con setTitle: #"Hello"];
UIBackgroundConfiguration * back = con.background;
[back setStrokeColor: UIColor.labelColor];
[back setStrokeWidth: 3];
[back setBackgroundColor: [UIColor redColor]];
self.button.configuration = con;
Result:

It happens that 'button.configuration.background' property is not available in the Xcode 13 beta 5 for Mac Catalyst.
One have to wait for newer Xcode release to get this feature working from code.

Related

UIBarButtons disappeared in iOS 9.2

I have just upgraded one of my Apps under development to iOS 9.2 and I have found that all navigationbar UIBarButtons have just disappeared and are not shown on the navigation bar.
BTW: I'm using the UIBarButton custom class called BBBadgeBarButtonItem
from here
Update 1
Here is a snippet from the code I used to add the UIBarButtonItem
// Add the search button
UIImage* searchBtnImg = [UIImage imageNamed:#"searchBarButton"];
searchBtnImg = [self ipMaskedImage:searchBtnImg color:[UIColor pddAppSelectedIconColor]];
CGRect frame = CGRectMake(0, 0,searchBtnImg.size.width,searchBtnImg.size.height);
UIButton* searchBtn = [[UIButton alloc] initWithFrame:frame];
[searchBtn setBackgroundImage:searchBtnImg forState:UIControlStateNormal];
[searchBtn addTarget:self action:#selector(_searchContent) forControlEvents:UIControlEventTouchDown];
self.searchBarButtonItem = [[BBBadgeBarButtonItem alloc] initWithCustomUIButton:searchBtn];
self.searchBarButtonItem.shouldHideBadgeAtZero = YES;
self.searchBarButtonItem.badgeValue = #"0";
self.navigationItem.leftBarButtonItem = self.searchBarButtonItem;
Update 2
I see the following error message
<Error>: CGContextSetFillColorWithColor: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
and from this answer it seems to be an Apple Bug
I have figure it out, the ImageCatalog for random reason have make the custom BarButtonItem Unassigned for some unknown reason.... What a stupid thing ;(
Also, as I general note I have noticed that opening Xcode project for iOS9.1 on newer Xcode 7.2 or vice versa I got some of the already added images into the ImageCatalog to be in Unusigned state and the App couldn't see it until I fix that in ImageCatalog.

(iOS) alpha not works when run app

I have hours trying to solve this and researching about this problem without results. This is my problem:
I'm using a ViewController in a existing project and over this I use an UIIMageView and a UIView at the same level. Then I set them alpha value in these two elements (alpha = 0.5) using Interface Builder. When I run the project on Simulator the alpha value not make effect and they looks like with their alpha value = 1. I made this same procedure in a new project and when I run the alpha effect is visible. I tried check/uncheck opaque option, set alpha value programatically as property or using method setAlpha, as well as set opaque value with code and it doesn't works. This problem happens with device too.
Anyone have a solution?
Check whether you import
#import <UIKit/UIKit.h>
UIIMageView.alpha = 0.4;
OR check with this
UIImage *wheelImage = [UIImage imageNamed:#"wheel#2x.png"];
UIImageView *imageView = [[UIImageView alloc]initWithImage:wheelImage];
imageView.frame = CGRectMake(50, 50, wheelImage.size.width, wheelImage.size.height);
imageView.alpha = 0.2;
[self.view addSubview:imageView];
Did you forget to connect your outlet in the storyboard and the property?

How to use template rendering mode in Xcode 6 Interface Builder?

I'm trying to use images with template rendering mode enabled in Interface Builder but I can't get it working. With buttons everything works ok but with ImageViews the tintColor is not applying to the image.
I have enabled "Vectors type" (I'm using pdf) and "Render as Template Image" in the Image assets. What am I doing wrong?
I've hit the same problem. I think this is a bug.
You could dup this radar http://openradar.appspot.com/radar?id=5334033567318016, which refers to this minimal example app https://github.com/algal/TemplateImagesBrokenDemo.
I know of two workarounds for this problem
wrap in UIButton
Since tintColor works for UIButtons, one workaround is instead of UIImageView just to use a custom-type UIButton with userInteractionEnabled=false. If you disable the button's interactivity with UIView.userInteractionEnabled (as opposed to with UIControl.enabled), then you won't change the appearance of the image.
manually re-set the image in code
Another workaround is to re-set the .image property in code, after the UIImageView has been loaded from the nib. This works because setting an image in code seems to be what triggers the templating logic. For this to work, you need to re-set the image to its existing value in a way that won't be optimized away in the compiler. A snippet like this in awakeFromNib has worked for me:
override func awakeFromNib() {
super.awakeFromNib()
if shouldSetImagesManually {
// the following three-lines should in theory have no effect.
// but in fact, they ensure that the UIImageView
// correctly applies its tintColor to the vector template image
let image = self.templateImageView.image
self.templateImageView.image = nil
self.templateImageView.image = image
}
In my case the problem occures if the app is built with iOS8 SDK and is running on iOS 7.
My workaround is:
// this is the code that *should* work and does so on iOS 8
UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
[self.iconImageView setTintColor:tintColor];
self.iconImageView.image = [self imageForIconImageView]; // image is loaded from a pdf-resource (asset catalog set as Template) with imageNamed:#"resourceName"
// this is the workaround to get tint on iOS 7
if (!IS_IOS8_OR_HIGHER) { // macros checking iOS version*
UIImage *templateImage = [self.iconImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.iconImageView.image = templateImage;
}
// * - macros is defined like so:
// #define IS_IOS8_OR_HIGHER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
Here's the simplest code-less solution I found:
Another workaround that seems to work for me is to set the controller.view's tintColor. To get the default system tint color working:
self.view.tintColor = self.view.tintColor;
Like #algal's solution, it shouldn't make a difference, but it does.

Back-like arrow on iOS 7

I need to add a left bar button item in my app that looks like system back button, but is not the system back button, since it will appear on view controller that is the only vc of my navController's stack and execute my own code. Simply writing "Back" isn't really good for me, as I need to display the "<" arrow as well. Is there a way to programmatically create an arrow like that, without making image with that arrow?
You can use any Unicode character (anywhere in your code) for this.
You can find what you want here:
Xcode > Edit > Special Characters...
Search for arrow or back or browse the categories.
Then copy paste the character where required (in the XIB object's title or in the setTitle or setText methods like any other character)
something like:
Try this:
// After you create and place your backButton:
UILabel* arrowLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 20, 20)];
arrowLabel.text = #"<";
arrowLabel.textColor = [backButton titleColorForState:UIControlStateNormal];
arrowLabel.transform = CGAffineTransformMakeScale(1,2);
[backButton addSubview:arrowLabel];
If addSubview gives you trouble, try
[backButton insertSubview:arrowLabel atIndex:0];
Consider using a dummy UIViewController as a root view controller for your UINavigationController’s stack:
[[UINavigationController alloc] initWithRootViewController:[UIViewController new]];
[navController pushViewController:viewController animated:NO];
Then you can use my BackButtonHandler extension to handle back button action (as described in this thread) :
-(BOOL) navigationShouldPopOnBackButton {
[self dismissModalViewControllerAnimated:YES];
return NO;
}
Look at the UIBarButtonSystemItem enum under contants in the UIBarButtonItem documentation:
https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40007519-CH3-SW2
These are all of the button styles provided by Apple:
typedef enum {
UIBarButtonSystemItemDone,
UIBarButtonSystemItemCancel,
UIBarButtonSystemItemEdit,
UIBarButtonSystemItemSave,
UIBarButtonSystemItemAdd,
UIBarButtonSystemItemFlexibleSpace,
UIBarButtonSystemItemFixedSpace,
UIBarButtonSystemItemCompose,
UIBarButtonSystemItemReply,
UIBarButtonSystemItemAction,
UIBarButtonSystemItemOrganize,
UIBarButtonSystemItemBookmarks,
UIBarButtonSystemItemSearch,
UIBarButtonSystemItemRefresh,
UIBarButtonSystemItemStop,
UIBarButtonSystemItemCamera,
UIBarButtonSystemItemTrash,
UIBarButtonSystemItemPlay,
UIBarButtonSystemItemPause,
UIBarButtonSystemItemRewind,
UIBarButtonSystemItemFastForward,
UIBarButtonSystemItemUndo, // iOS 3.0 and later
UIBarButtonSystemItemRedo, // iOS 3.0 and later
UIBarButtonSystemItemPageCurl, // iOS 4.0 and later
} UIBarButtonSystemItem;
Perhaps rewind or undo would be close enough for you.

How do I use iOS7 controls without upgrading your nib files?

At this point in time I'd like to keep my code compatible with Xcode 4, therefore I don't want to upgrade my nib files.
However, I can't change the UISegmentedControl control tint colour and use the new iOS7 version of the control without upgrading the nib file.
I've seen ..
[NSUserDefaults standardUserDefaults] setObject:#Yes forKey#"UIUseLegacyUID"]
Which will keep iOS6 layout, I'm not sure if there is an future version or whether this would help?
With Xcode 5, you can change your XIB to use the property of Xcode 4 and iOS 6.
By default you have:
But, you can change the property for Xcode 4.6 and iOS 6:
You can change the tint color in the code like this:
UISegmentedControl *segmentedControl = ...;
// For backwards compatibility
if ([segmentedControl respondsToSelector:#selector(tintColor)])
{
segmentedControl.tintColor = [UIColor redColor];
}
You can set different segment image and color for each segment. For color you may use:
//get the subviews of the segmentedcontrol
NSArray *arri = [segmentedControl subviews];
//change the color of every subview(segment) you have
[[arri objectAtIndex:0] setTintColor:[UIColor redColor]];
[[arri objectAtIndex:1] setTintColor:[UIColor greenColor]];

Resources