UIButton imageEdgeInsets not updating at run time - ios

So here is my code, it's fairly strait forward.
CGFloat spaceing = 5;
self.premiumButton.imageEdgeInsets = UIEdgeInsetsMake(spaceing,spaceing,spaceing,spaceing)
NSLog(#"immage - %#", NSStringFromUIEdgeInsets(self.premiumButton.imageEdgeInsets));
right should update the Image to be in the center of the button with a 5 point padding on all sides(I've removed the text for this particular state)
but the log comes back with
immage - {0, 0, 0, 0}
Infact I placed this in initWithCoder which is how this view is being built from a xib and got the same thing despite the fact that in the interface builder I set everything.
What am I missing everything else on stack overflow has code samples that look just like mine marked as the answer but it's not doing anything for me.
I have tried the UIButton setTitleEdgeInsets method but no go.

- (void)layoutSubviews update imageEdgeInsets

Related

Possible to get UIButton sizeThatFits to work?

I have been using a method of resizing my UIButtons that is depreciated, and not very robust. For that and also other reasons, I want to get sizeThatFits to work for UIButtons. From what I've read online, I'm not sure if it should work (seems like it is working for some, but not others, the difference maybe between the style, I'm using custom).
Here is my simple test code to recreate the issue (I just put this in viewDidLoad to test, but shouldn't matter, and my real code is part of a large project):
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:#"This is a test with a long title that will need to word wrap to more than a single line when displayed on my tiny iPod in portrait view." forState:UIControlStateNormal];
btn.titleLabel.lineBreakMode = UILineBreakModeWordWrap; // depreciated - but nothing to replace it?
CGRect r = btn.frame;
r.origin.x = 0;
r.origin.y = 0;
r.size.width = 320;
r.size.height = [btn.titleLabel.text sizeWithFont:btn.titleLabel.font constrainedToSize:CGSizeMake(r.size.width,100000) lineBreakMode:btn.titleLabel.lineBreakMode].height; // Returns approx 86 and changes correctly if I change the title text
r.size.height = [btn sizeThatFits:CGSizeMake(r.size.width,CGFLOAT_MAX)].height; // returns 34 no matter what
btn.frame = r;
The sizeWithFont line is what I have been doing, and it works, but it isn't asking the actual control for the size, so not really safe and has been depreciated also. The sizeThatFits line is what I would like to get working, but it always returns 34 no matter what (probably the recommended/default height of a button).
I've been using the same sizeWithFont to resize UILabels and some other controls as well. I've updated them to use sizeThatFits and they work great, just UIButton isn't working the same as the others. I'm hoping there is a simple fix, like setting a property of the UIButton, to get this working?
My app only needs to support iOS 8+, not older versions.
Update: Based on the comments here How do I resize a UIButton to fit the text without it going wider than the screen? and the accepted answer, it seems like we might be stuck with sizeWithFont or other sub-par solutions... dang.
I fixed it using UIButton titleLabel instead of UIButton.
button.titleLabel?.sizeThatFits(labelFitSize)
Instead of
button.sizeThatFits(labelFitSize)
Good news is that it works, bad news you will need to handle yourself if the button as contentInsets or images...

UIButton not displaying background image on device or simulator

I really thought stuff like this wouldn't happen to me, but here it is:
I Setup some Buttons on the StoryBoard. When I Compile the App into a Device or the Simulator, one of the Buttons shows the Image and the Rest don't.
I Already Checked that the Images are assigned to the Target and that the Resources appear on the Project.
Any Ideas?
Well, this is Embarrassing.
Turns out I Was Modifying the superview.bounds Due to a Previous Interface Issues and i Forgot About them.
The Problematic Code:
// to Arrange the Layout:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 356, 421);
}
So I Removed This Line: self.view.superview.bounds = CGRectMake(0, 0, 356, 421); and Everything is now OK.
Lesson: DO NOT PLAY WITH THE BOUNDS OF YOUR SUPERVIEW IF YOU WANT AUTOLAYOUT TO WORK.
Thanks to #Maverick and #Fahim Parkar for pointing me on the Right Direction :-)

Calling a few [UIVIew setFrame:] in a row doesn't execute all of them

I've a strange problem with sliding in a UIView into another one while sliding out the other content of the view.
This is the code:
- (void)moveAddStudentViewIntoSuperView
{
CGRect viewFrame1 = self.viewThatShoudlDisappear1.frame;
CGRect viewFrame2 = self.viewThatShoudlDisappear2.frame;
CGRect newFrame = self.viewControllerThatshouldAppear.view.frame;
viewFrame1.origin.x = -300;
viewFrame2.origin.x = -300;
newStudentFrame.origin.x = 0;
NSLog(#"\n 1: %# \n 2: %# \n 3: %#", self.viewThatShoudlDisappear1, self.viewThatShoudlDisappear2, self.viewControllerThatshouldAppear.view);
[self.viewThatShoudlDisappear1 setFrame:viewFrame1];
[self.viewThatShoudlDisappear2 setFrame:viewFrame2];
[self.viewControllerThatshouldAppear.view setFrame:newFrame];
NSLog(#"\n 1: %# \n 2: %# \n 3: %#", self.viewThatShoudlDisappear1, self.viewThatShoudlDisappear2, self.viewControllerThatshouldAppear.view);
}
(Usually I'd do the setFrames in a UIView animation but it doesn't matter for this example as it doesn't work anyway)
What happens is that the view that should slide in or rather is now located at (0,0) appears but the other views dont move away. And are still displayed under the new view.
What is strange, is that the log outputs that all views are in the correct position. [self.view setNeedsLayout] between the setFrame calls doesn't change anything either and even more interesting is that if I remove the setFrame from the new view the views that should disappear do actually disappear correctly.
There is a typo on this line:
CGRect viewFrame2 = self.viewThatShoudlDisappear1.frame;
Presumably, this should be:
CGRect viewFrame2 = self.viewThatShoudlDisappear2.frame;
I've seen odd things like this when I've accidentally used UIKit from a background thread. UIKit should only be used from the main thread.
Ok so I think I don't fully understand AutoLayout. Due to a tip from Toto, I tried to test it under iOS 5 and had to deactivate AutoLayout everywhere to run it.
It instantly worked with iOS 5. Afterwards I switched back to iOS 6 without activating AutoLayout again and it worked there perfectly too.
My solution is: Deactivating AutoLayout in the XIB file(s).
But I can't think of a way where this should be a default behavior. Maybe I miss a point of AutoLayout or this is a weird bug. As soon as I've talked to devs who are more into it, I'll probably submit a bugreport if necessary.

Dynamically reposition a UI Button

I'm trying to change the position of my UIButton, which was positioned and sized in interface builder. I'm stumped.
I tried this code at the end of viewDidAppear:
[_smartphoneButton setFrame:CGRectMake( 20, 20, 100, 50 )];
Nothing changes. And yet i know _smartphoneButton is valid, because _smartphoneButton.hidden = YES; works, as well as changing the UIButton image.
And suggestions?
PS, none of these work either:
_smartphoneButton.frame = CGRectMake( 20, 20, 100, 50 );
or
_smartphoneButton.center = CGPointMake(10.0f, 10.0f);
Thanks in advance!!!
Agree with CodaFi, put a break point to see the value of _smartphoneButton.
But even if viewWillAppear will work, I would suggest moving your code to viewDidLoad for the following reason.
viewWillAppear can get call several time in the live of a ViewController and you will be modifying the position of your button ofter for nothing.

iPhone Custom UISlider preload and rounded edges issues

I'm trying to implement a custom UISlider, I've extended it with a class called UISliderCustom which has the following code:
#implementation UISliderCustom
- (id)initWithCoder:(NSCoder *)aDecoder{
if(self == [super initWithCoder:aDecoder]){
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 200, 13);
UIImage *slideMin = [[UIImage imageNamed:#"slideMinimum.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
UIImage *slideMax = [[UIImage imageNamed:#"slideMaximum.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
[self setThumbImage:[UIImage imageNamed:#"slideThumb.png"] forState:UIControlStateNormal];
[self setThumbImage:[UIImage imageNamed:#"slideThumb.png"] forState:UIControlStateHighlighted];
[self setMinimumTrackImage:slideMin forState:UIControlStateNormal];
[self setMaximumTrackImage:slideMax forState:UIControlStateNormal];
}
return self;
}
#end
I ran into two small problems
When I slide over the slider to one of the edges (progress = 0.0 / progress = 1.0), I can clearly see "left overs" in the sides, im not sure how to handle that as well, unfortunately :)
Slider images:
Problem:
I see the regular UISlider (blue and silver) for a couple of seconds, and only then the custom graphics is loaded, or when i actually move the slider. I'm not sure why this is happening.. EDIT: This only happens in the simulator, works fine now.
Thanks in advance for any assistance :)
Shai.
You have no need to subclass UISlider to achieve this effect, and if you did you certainly wouldn't set the track images in the drawRect method. drawRect should contain drawing code only, it is called whenever any part of the control needs redrawing.
Set the thumb and track images in a separate method, either within your subclass (called from initWithFrame and initWithCoder) or in the object that creates the slider in the first place. This only needs to be done once, when the slider is first created. Don't override drawRect.
You don't need to call awakeFromNib manually either, unless you have some specific code in there as well? That would be a common place to set custom images in a subclass, if you only ever used the slider from IB.
For the square ends, the problem is that the extreme edge of your track image is square, so it is showing around the thumb. Make both ends of the track image rounded, with a 1px stretchable area in the middle, like this:
I just had a very similar problem myself. It turned out that the size (width x height) of the slider that I added in interface builder didn't match the sizes of the images I was using to customize the slider. Once I made them match, those "leftovers" at the ends of the slider went away.

Resources