UIButton changes height after setBackgroundImage - uibutton

This is with ios 6.x, simulator and on-device, xcode 4.6.
I have a RoundRect button in a storyboard that is linked to an outlet in my code. In viewDidLoad, I do the following:
UIImage *bgImage = [[UIImage imageNamed: #"bgButton.png"]
resizableImageWithCapInsets: UIEdgeInsetsMake(8, 8, 8, 8)
resizingMode: UIImageResizingModeStretch];
[ButtonOutlet setBackgroundImage: bgImage
forState: UIControlStateNormal];
The button is has a height of 44 in the storyboard and there is no code that changes it, however with the setBackgroundImage call viewDidAppear reports the height of the button frame as 52, without that call it's still 44. The background image is a 36px square (72#2x). The size of the insets doesn't appear to make a difference.
Thanks for your help.

Adding a constraint in interface builder for the height of the affected button fixed the problem.

Related

Setting UIButton image results in blue button in iOS 7

On iOS 6 SDK I wrote the following lines of code to display an image inside a button:
NSURL *thumbURL2 = [NSURL URLWithString:#"http://example.com/thumbs/2.jpg"];
NSData *thumbData2 = [NSData dataWithContentsOfURL:thumbURL2];
UIImage *thumb2 = [UIImage imageWithData:thumbData2];
[btn2 setImage:thumb2 forState:UIControlStateNormal];
[self.view addSubview:btn2];
But now with Xcode 5 and iOS 7 this doesn't work. The button doesn't contain the image. The button is filled with blue color.
In iOS7 there is new button type called UIButtonTypeSystem NS_ENUM_AVAILABLE_IOS(7_0), // standard system button
Check your .xib file and change button type to Custom
To do this programmatically, add this line to the viewDidLoad:
[UIButton buttonWithType:UIButtonTypeSystem];
It seems iOS 7 is using the image provided just as an Alpha mask for displaying the button's tint color.
Changing the button type to UIButtonTypeCustom did the trick for me (thanks user716216!).
Setting the image as background doesn't always work if you already have a background image, as was my case.
Swift 3, 4, 5 :
let image = UIImage(named: "my-image")
myButton.setImage(image.withRenderingMode(.alwaysOriginal), for: .normal)
There's a good chance that the image is there and you just can't see it. Try changing the button's type to UIButtonTypeCustom. If that doesn't work, set the button's background color to [UIColor clearColor];
For swift:
let aButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
The issue is the TintColor. By default, iOS throws a blue tint color over every button. You can get around it through 3 ways.
Change the tint color. [button setTintColor:[UIColor blackColor]];
This may color your image in ways you don't want it to.
As most other suggested, set the background image. [button setBackgroundImage:[UIImage...]];
Add an UIImageView to your button.
UIImageView * img = [[UIImageView alloc] initWithImage:[UIImage...]];
[button addSubView:img];
I had the same issue.
On my storyboard I had a button without any image.
I would then assign the image in the code.
IOS 7 came and I got a lot of blue images.
The resolution was simple yet confusing. If I assign any image on the storyboard and then change the image at run time it works fine.
You always must specify a starting image on the storyboard even if you are not going to use it.
This worked for me
[myButton1 setBackgroundImage:[UIImage imageNamed:#"phones.png"] forState:UIControlStateNormal];
Note:Remove front image before doing this.
Old thread, but I wanted to chime in because I just had the same problem. The issue was just that you are calling setImage when you should call setBackgroundImage.
In iOS 13 -- just set the Tint property to White, while keeping the type of the UIButton as Custom
None of the given solutions were working for me. If you do not set an initial image in Storyboard, you can still change the image of the button by using setBackgroundImage.
For your example, only a minor change is needed.
NSURL *thumbURL2 = [NSURL URLWithString:#"http://example.com/thumbs/2.jpg"];
NSData *thumbData2 = [NSData dataWithContentsOfURL:thumbURL2];
UIImage *thumb2 = [UIImage imageWithData:thumbData2];
[btn2 setBackgroundImage:thumb2 forState:UIControlStateNormal];
[self.view addSubview:btn2];
This Problem is called blue color problem of the button in xcode.
When we make button by code the button shows the blue tint color by default.This can be solved byt assigning tint color to black or white accordingly to your cell's color.
The code is :
UIImage *closebtnimg = [UIImage imageNamed:#"icon_uncheck.png"];
UIImage *closebtnimg1 = [UIImage imageNamed:#"icon_checked.png"];
Custombutton *button = [Custombutton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(52, 66, 25, 24)];
[button setBackgroundImage:closebtnimg forState:UIControlStateNormal];
[button setBackgroundImage:closebtnimg1 forState:UIControlStateSelected];
[button setTintColor:[UIColor whiteColor]];
[cell.contentView addSubview:button];
[button addTarget:self action:#selector(changeImage:) forControlEvents:UIControlEventTouchUpInside];
Using Xcode 9.2 none of the above solutions worked for what I was looking for.
I was looking for a solution that will let me set .normal and .selected UIControlState images inside the storyboard for their original rendering mode, but, inside the Swift file, no string literals should exist regarding the image names.
Basically, inside your code you will get the image you set inside your storyboard for .normal state and re-render it as .alwaysOriginal (Same for .selected state), then, you will set that image (which is now rendered as original and won't be affected by the tint) for the relevant state (.normal and .selected) of your UIButton.
Here it is:
// Get your .normal image (you set via your storyboard) and render it as original
let unselectedImage = yourButton.image(for: .normal)?.withRenderingMode(.alwaysOriginal)
// Set your normal image but this time rendered as original
yourButton.setImage(unselectedImage, for: .normal)
// Same for selected state
let selectedImage = yourButton.image(for: .selected)?.withRenderingMode(.alwaysOriginal)
yourButton.setImage(selectedImage, for: .selected)
This way you can set your button image states and if the image name will change, it won't affect your code.
making the tint color as clearcolor for all the four states(Default,Highlighted,selected,disabled) worked for me.
In Swift 4, initialize your UIButton and assign uyour image Data as follows:
let myButton = UIButton(type: .cutsom)
myButton.setImage(UIImage(data:myImageData), for: .normal)

In iOS6, XCode 4.5, UIScrollView is not Scrolling, despite contentSize being set

I've been banging my head against the wall for the last hour trying to get my scrollView to scroll, but to no avail. In viewDidLoad I have
NSURL *url = [FlickrFetcher urlForPhoto:self.photoData format:FlickrPhotoFormatLarge];
NSData *imageRawData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageRawData];
self.scrollView.delegate = self;
self.imageView.image = image;
self.scrollView.contentSize = image.size;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
I have the imageView view mode set to top left.
My UIScrollView was created by selecting my imageView, then Editor -> Embed in -> ScrollView.
Anything else I can check/try?
If you have created your scrollview through nib, and if that nib has autolayout feature then it will not let you scroll.
So go utility window of nib.
Select First tab of utility window.
Remove autolayout and run the application
Checklist:
Is image really downloaded? (so it actaullly has size?)
Is scrollview outlet set?
Is imageView added as a subview of scrollView?
Btw. Don't know if this is just sample code or real but if it's real then it's really bad idea to download data synchronously and even worse idea to do it in viewDidLoad.
I guess it because you have image view embedded in scrollview,so its frame is becoming to imageview's frame. when frame size and content size are equal, scrollview wont scroll. Try setting scrollview's frame pragmatically to some fixed rectangle. ScrollView's contentSize's height and width should be greater then scrollview's frame's height and width. Give it some space to scroll:) In your case , they both are equal I guess.

iOS UISearchBar text field background

I'm trying to customize the text field of the UISearchBar on iOS, but I'm having issues. Using the following method:
[searchBar setSearchFieldBackgroundImage:searchFieldImage forState:UIControlStateNormal];
gives me the image in the text field, but it is TINY. The image is only 40x15 px dimension, and is used for stretching. I'm creating the image as follows:
UIImage *searchFieldImage = [[UIImage imageNamed:#"input_15x40.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(7, 19, 7, 20)];
However, it seems that this appearance modification doesn't stretch the image - just takes it as is. How can I go about customizing the textfield image of the UISearchBar with a stretchable image?
EDIT
I should say that the bar is stretched horizontally, but it is NOT stretched vertically, and thus is only 15px height.
The only problem that I can see in your code is that you create the var named searchFieldImage and use it as searchField.
This code worked for me:
UIImage *searchFieldImage = [[UIImage imageNamed:#"input_15x40.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(7, 19, 7, 20)];
[searchBar setSearchFieldBackgroundImage:searchFieldImage forState:UIControlStateNormal];
-
Edit:
In the height, the image will not stretch because the height of the image will set the height of the view that wraps it.
let searchTextField = searchBar.valueForKey("_searchField") as? UITextField
searchTextField?.backgroundColor = UIColor.redColor()

UIScrollView not scrolling when adding item in IB and code

When I create a Scrollview on my scene, and then add a button to scene in IB. Then I go into the code, set the content size, enable user interaction and add another button. When I run the program in the simulator the Scrollview does not work, if I remove the button that is in IB on the scene it works just fine. Is it not possible to add items to the scrollview both in IB and programmatically?
EDIT: I thought it may be something in the app I already had. So I decided that I would create anew project and all it has in it is code, and the scene picture below. It is indeed added below the ScrollView.
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton setTitle:#"My Button" forState:UIControlStateNormal];
myButton.frame = CGRectMake(100, 100, 150, 50);
[scrollView addSubview:myButton];
scrollView.userInteractionEnabled = YES;
[scrollView setContentSize:CGSizeMake(320, 1000)];
Here your scrollView is not scrolling due to the autoLayout, uncheck the auto Layout if you are not using.
I Just made a similar to your requirement. It is working fine, and after allowing autoLayout it just stopped scrolling.
The auto layout constraints fits to the visible part of the screen, if the objects in scrollView are more then screen size, it will scroll.
So my suggestion if you are not using autoLayout just uncheck it, and works fine.
Here is an helpful link: http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html#//apple_ref/doc/uid/TP40012166-CH1-SW19
Basically what this says is that, with auto-layout you don't and shouldn't have to use setContentSize:. Instead your inner view should have it's edges snapped to the edges of the scrollview. Let me demonstrate how I solved it.
scrollBackground : a view that contains every other view that needs to scroll in the scrollview.
[scrollview addSubview:scrollBackground];
[scrollview addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"V:|[scrollBackground(1000.0f)]|"
options:0 metrics:nil
views:NSDictionaryOfVariableBindings(scrollBackground)]];
[scrollview addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"H:|[scrollBackground(==scrollview)]|"
options:0 metrics:nil
views:NSDictionaryOfVariableBindings(scrollBackground)]];
The key here being those | at beginning and end of the VisualFormat String. These will tell the scrollview what is the contentSize. Of course if you have a contentSize smaller than the frame size of the scrollview it won't scroll in that direction. In my example this is true for width. It only scrolls up and down.
Make sure you set your content size in viewDidLoad or at some point after the view has already been loaded from the nib file.
As vishy Pointed out, your Button should be part of the ScrollView's Hierarchy, else you'll just be scrolling an empty view.
In the case you posted, the scrollview will not scroll because all of the content is visible. Try changing that last line to:
[scrollView setContentSize:CGSizeMake(50, 50)];
and it will start scrolling, because the content size is smaller than all of the content in the view.
check d2burke answer in this question
you should place your code in viewWillLayoutSubviews instead of viewDidAppear

UINavigationBar tint color flashing in iOS 4

The app I'm working on has a custom nab bar but supports iOS 4.2-iOS 5, so I need to set the UINavigationBar background and tint in this old school way in my app delegate.
#implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
self.tintColor = [UIColor colorWithRed:42.0/255.0
green:164.0/255.0
blue:182.0/255.0
alpha:1.0];
UIImage *img = [UIImage imageNamed:#"navbar_bg.png"];
[img drawInRect:CGRectMake(0.0, 0.0,
self.frame.size.width,
self.frame.size.height)];
}
#end
This works for the most part, but I noticed when the app is first starting, the UIBarButtonItems flash the default navigation bar color for a second before they correct themselves and change color to match the navigation bar. Interestingly, the navigation bar itself uses the background image correctly from the get-go.
To be clear, I'm using setBackgroundImage for UINavigationBar on iOS 5 devices which works as expected so the flash is only in iOS 4.
Anyone have any insight on why this would happen and/or how to fix it?
The bar button items are the wrong color? You can manually set their tint color in viewDidLoad: to the tint color
navigationBar.rightBarButtonItem.tintColor = [UIColor ...]
if you're using a nib file. Otherwise you can do the same thing in loadView: . Either way this code will get executed as part of the initial draw loop so you'll have the proper color without any flashing.
Also for future reference, it's technically incorrect to override a method inside a category. (The latest version of Xcode, 4.3, will give you a warning about this). You should either properly subclass UINavigationBar or do "method swizzling". But that's pretty tough so don't worry about it right now :)
If you call the class with the code referenced in viewDidLoad try moving it to awakeFromNib