UIButtonTypeCustom image deformed - iphone

customBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[customBtn setFrame:CGRectMake(200,200,68,68)];
UIImage *btnImage = [UIImage imageNamed:#"dash_pulsante_attivo"];
[customBtn setImage:btnImage forState:UIControlStateNormal];
[customBtn addTarget:self action:#selector(triggerMeasurement) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:customBtn];
I'm building a custom button that should be using a 68x68 png for it's normal state.
But the image looks deformed: it should be a circle, but it display as an oval.
Any hint or suggestion why it is happening? Curiously, I've tried to swap with another circular png, 220x220, and everything works as expected.

I hope this error happened, because of image size, check whether the image size is 68x68.
nothing wrong in your code.

check the image "dash_pulsante_attivo" resolution. If it's less than 68*68 it supposed to get distorted. Higher resolution won't have distortion problem.
If you want resize your image programatically. You can do like this.

Related

How to set UISlider' trackImage (using pattern)

I hope to how to set UISlider's trackImage.
My image is this.
I want to use pattern.
But, I cannot find way.
Please tell me hint.
You can create a resizable image and make it so that the resizing is done using tiling. As you don't have any caps on the image you can do something like this...
UIImage *trackImage = [[UIImage imageNamed:#"TheImage"] resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeTile];
Then use this image on the slider...
[slider setMinimumTrackImage:trackImage forState:UIControlStateNormal];
This will then tile the image horizontally. As long as your pattern matches up edge to edge then it will work.
You can try creating a UIColor using the image as a pattern, and then setting it in the slider.
[slider setMinimumTrackTintColor:[UIColor colorWithPatternImage:/*your image*/]];

UIButton setImage not working

I'm losing my mind over this one. I have UIButton connected as Outlet. I want to change it's image. In the viewDidLoad function, I try to set the image like so:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
Nothing happens. However, if I use ImagePicker, it somehow works. In the ImagePickers function "didFinishPickingImage", I repeat the exactly same command as above for setting image and it works, the image is displayed normally.
I've been thinking that maybe the button's image is not refreshing itself, but trying to call [button1 setNeedsDisplay], or [button1.imageView setNeedsDisplay] or even [button1.imageView.image setNeedsDisplay] does nothing.
Does anyone have any idea about this? I've wasted two hours by now and I'm really getting frustrated, because I'm certain that the reason must be so stupid it's unbelivable.
Please check your button type.
If your button type is "System" you should change it to "Custom"
Two things to do here:
#1, change your code to:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
and #2
make sure your UIImage returns a valid image.
In other words,
UIImage * imageToSet = [UIImage imageNamed: #"house.png"];
if(imageToSet)
{
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
} else {
// if you see this line in your console, then you know where to look for a problem
NSLog( #"why is my image object nil?");
}
For anyone who will find themselves in a similar situation; I was using the mentioned button inside a custom cell for table view. However, the cells aren't loaded right away (i.e. inside viewDidLoad/viewWillAppear etc.), but inside the tableView:cellForRowAtIndexPath function. All my button variables were nil at that point. My solution was to load the image after the cell has been created and it has worked straight away afterwards.
Here are a couple additional notes. UIButton setImage: forState: is the correct method:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
imageNamed is a great convenience method for grabbing the image, but make sure it returns an object. Forgetting to include the image file in the current target gets me all of the time.
[UIImage imageNamed:#"house.png"]
You also don't need the extension. The SDK works this out.
[UIImage imageNamed:#"house"]
And even though UIControlState is a bit mask, you cannot OR the values together. This does not not not work and I must must must remember this because it gets me every time I use the call.
// NO NO NO
[button1 setImage:[UIImage imageNamed:#"house"] forState:UIControlStateNormal|UIControlStateSelected];
// YES
[button1 setImage:[UIImage imageNamed:#"house"] forState:UIControlStateNormal];
[button1 setImage:[UIImage imageNamed:#"house"] forState:UIControlStateSelected];
Was getting the same problem when UIbutton was in UITableViewCell.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"detail.png"] forState:UIControlStateNormal];
should work in UITableViewCell
Glad to know that the problem is solved but none of the answers actually addresses the problem.
Generally, if the code is correct, then the error shifts from "syntax error" to the "logical error" category. There is no definite guide to handle it but here is a small checklist that can help anyone to troubleshoot their code.
1) The IBOutlet is not connected or renamed.
2) Make sure that the UIButton type is custom.
3) The image is set (more than once), somewhere else in the code.
4) You are trying to set the Image through any sync method which is not using the main thread. (There are several threads on that alone).
5) If you are nesting the images as subviews, make sure the problem isn't with their parent view.
6) If it is appearing in Simulator but not in the device, It's a lettercase (Uppercase, lowercase difference in the code and the filename.
7) Modern simulators works with very low GPU memory on older machines. You can tweak the simlator options to make it appear. E.g (Command + Right Arrow) twice to change the simulator orientation and your changes will appear.
There are few other but common pitfalls where developers usually overlook
1) The image doesn't exist OR you are making a spelling mistake.
2) The filetype is different than mentioned. (JPG, PNG).
Last thing you'll want to check - make sure you're setting the image on the main thread! Just ran into an issue where I was setting a button image in a callback from ALAssetLibrary (fetching images from photo library). The image wouldn't update until I tapped the button. Turns out the callback was happening off main...
for those having issues with system images not appearing, just use systemName: instead of named
if let starImg = UIImage(systemName: "star.fill") {
button.setImage(starImg, for: .normal)
}
It's for ios13 and later...
For me it was to move the line:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
from awakeFromNib method
to viewDidLoad method
I guess,
don't create like this
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
by this create method ,UIButton is create by use default type,so your background image is not work.
try this,
UIButton *nextButton = [[UIButton alloc] initWithFrame:CGRectMake(9, 154, 300, 48)];
or other,except buttonWithType
This is happening because the state of the Button doesn't stays selected once clicked by default.
I solved it by making an IBaction on that button click and toggling the selected state.
-(IBAction) checkButtonClicked:(id)sender{
checkButton.selected = !checkButton.selected;
}
In my case, it is drawn by custom animation code and not set by the image, so it doesn't work by setting any image, it has to change the animation code.
With images, you have to import them into the project not as references but as copies. So when you go to add files to project, choose "Create groups" instead of "Create folder references". Also make sure "Copy items if needed" is checked.
This is confusing because importing as references works when you are using images as textures (e.g. for Sprites). However, it doesn't work when you want to use images for buttons (e.g. for using image name in [UIImage imageNamed:#"house.png"]
I faced this same issue of the image not being shown on the UIButton.
I had to change this line -
myButton.setImage(<my_UIImage_object>, for: [.normal, .focused])
to this -
myButton.setImage(<my_UIImage_object>, for: .normal)

Why are these UIImages so "blurry"?

In an app I'm working on, I've got a few UIImages which for some reason come out really blurry. This specifically applies to two icons I use which are fairly small (80x15 and 65x15).
(Update: added iPad Simulator output as well -- it is blurry just as the iPad output)
Top left and right are original images, bottom left and right are how they come out on the iPad. I actually got complaints about these being awfully blurry from users, so it's not just me.
The code where one of these is put in place looks like this (can show code for other one at request):
UIButton *bWeb = [[UIButton alloc] initWithFrame:
CGRectMake(attriboffset, height - 20.f, 65.f, 15.f)];
[bWeb addTarget:self action:#selector(clickWebLink:)
forControlEvents:UIControlEventTouchUpInside];
bWeb.userInteractionEnabled = YES;
[bWeb setImage:[UIImage imageNamed:#"button-weblink-65x15.png"]
forState:UIControlStateNormal];
[bWeb setImage:[UIImage imageNamed:#"button-weblink-highlighted-65x15.png"]
forState:UIControlStateHighlighted];
[self addSubview:bWeb];
[bWeb release];
The original images are (in case you think it might be a formatting issue with the actual PNG files): ,
Make sure that all numbers in UIButton's frame are rounded/truncated to integers.
What is attriboffset?
Like hoha says, if the numbers are not integers, you will end up with fractional offsets, and devices will do some blurry antialiasing to compensate for that. The numbers should not have fractions.
I think that for some reason the image is being rendered with some kind of unnecessary processing that is causing the quality loss.
Try changing the contentMode property of your UIButton to UIViewContentModeCenter. The default is UIViewContentModeStretch.
Open your images in preview and resave them.

Stretchable image stretching part wider than 1px

I would like to create a UIButton which uses a stretchable image as Background image such as that I can easily resize the button for different labels etc.
So I created the following code which works fine:
UIImage *bgImage = [[UIImage imageNamed:#"Button-Template.png"]stretchableImageWithLeftCapWidth:2 topCapHeight:2];
UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
loginButton.frame = CGRectMake(180, 280, 112, 40);
[loginButton setBackgroundImage:bgImage forState:UIControlStateNormal];
// some more stuff
Now here is the catch: The iPhone SDK assumes that the strechable part of the image is exactly one pixel in width, which is not the case in my image as I want to create a pattern, which requires a repetition every two pixels (so 2 Pixels are one pattern unit). I have found no information in the docs whether it is possible to alter the value of the strechable part width (in my case 2 instead of 1), does anybody know how to do this or how I could achieve my goal with a workaround? Writing the stretching part on my own seems a little far fetched right now (though I might have to get back to this).
Thanks!
From iOS 5.0 on you could use resizableImageWithCapInsets:
Check UIImage Class Reference
But this method only works on iOS >= 5.0 devices, so that can be a
turn down for now.
There is no API for using 2 pixels as the stretch width. You'll have to implement this behaviour yourself in a custom view, or use an image with a specific width.

How is a UIButton's image set programmatically?

How does one set the image of a UIButton from within the code?
I try the following but it just leaves the button as a white square.
[A1 setImage:[UIImage imageNamed:[NSString stringWithFormat:#"m1.10001.png"]] forState:UIControlStateNormal];
Your image construction seems a bit overly complicated, but it should work. Don't forget to use the correct button type (custom):
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"m1.10001.png"] forState:UIControlStateNormal];
With newer SDKs you can omit the .png. Make sure that the image actually exists (you can store it in a temporary variable and check for nil, for example).
And of course make sure that the button exists (or is bound), i.e. non-nil, when setting the image.