Dynamically reposition a UI Button - ios

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.

Related

UIButton imageEdgeInsets not updating at run time

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

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 :-)

Programmatically create subview that covers the top 50% of the iPhone screen

I have a subview and I have been customizing its size by using the frame property and setting its value to the CGRectMake function's parameter values.
I have slowly but surely been changing the CGRectMake parameters and re-running the app to get the subview to the correct position on the screen but I know there has to be an easier way.
Here is what I am currently doing:
UIImageView *halfView = [[UIImageView alloc]initWithImage:image];
[self.view addSubview:halfView];
halfView.frame = CGRectMake(0, 0, 320, 270);
Is there a way that I can stop having to manually enter those 4 parameters into CGRectMake, and just set it to the top 50% of the screen?
Here is what I want the subview to look like on the iphone's screen:
halfView.frame = CGRectMake(0, 0, 320, self.view.bounds.size.height/2);
you just take the height and divide it by two
You should also probably change 320 to self.view.bounds.size.width
I suggest reading this post to really get a grasp of UIViews and working with them:
UIView frame, bounds and center

elegant (i.e., non-hard-coded) way to position `UITextField`, `UITextView`, and `UIButton` relative to each other?

I have the following screen in my app.
Right now the positioning is all hard-coded, and it's not pretty. It's one textview with several \ns in the middle and a textfield and button carefully positioned, experimenting pixel by pixel, and then hard-coded in, which is fine except then if I switch to a 4-inch screen it's useless. Plus it's just ugly.
I've been looking around stackoverflow trying to find answers, and I found some things about creating a CGPoint at a specific UITextPosition, but unfortunately I'm too much a novice to understand the answers.
Is there an elegant way to soft-code these positions relative to each other?
Thanks for your help.
EDIT: Here's the positioning code:
if (!optOut) {
optOut = [[UITextView alloc] initWithFrame:CGRectMake(20, 95, [[UIScreen mainScreen] bounds].size.width - 20, 200);
optOut.backgroundColor=[UIColor clearColor];
optOut.text = #"\n\n\nI hope to update the Haiku app periodically with new haiku, and, if you'll allow me, I'd like permission to include your haiku in future updates. If you're okay with my doing so, please enter your name here so I can give you credit.\n\n\n\nIf you DON'T want your haiku included \nin future updates (which would make \nme sad), check this box.";
}
[self.view addSubview:optOut];
if (!checkboxButton) {
checkboxButton = [UIButton buttonWithType:UIButtonTypeCustom];
checkboxButton.frame = CGRectMake(236, 260, 44, 44);
[self.view addSubview:checkboxButton];
}
[textView resignFirstResponder];
if (!nameField)
{
nameField=[[UITextField alloc] initWithFrame:CGRectMake(40, 223, 240, 30)];
[self.view addSubview:nameField];
}
Instead of placing optOut at (20, 95, [[UIScreen mainScreen] bounds].size.width - 20, 200), I'd like to be able to put it at (say) (20, [[UIScreen mainScreen] bounds].size.height/2-100, [[UIScreen mainScreen] bounds].size.width - 20, 200). But if I do that--if the starting position of optOut moves depending on how tall the screen is--then I have to move nameField and checkBox too, and I don't know how to keep them in the same position relative to optOut.
So first, I would put the second part of that UITextView (after all the returns) into its own object and tack it on to the view by itself. And then the simplest way to go about this with what you have is to ask the elements directly for frame placement, so where you have
checkboxButton.frame = CGRectMake(236, 260, 44, 44);
do something like (and I apologize I if the syntax is a bit off but you can get the idea)
checkboxButton.frame = CGRectMake([optOut center].y + pixelsToMoveOverToWhereYouLikeIt, [optOut center].y + pixelsToMoveDownToWhereYouLikeIt , 44, 44);
And so on for the others. That would make all the view either relative to each other or to one the first textview, depending on which object you reference.
It would be a lot easier to break it apart into different components that you can position individually, and either use constraints to automatically position them or move them individually in code. Also, a UILabel would be better to display the static text, since you don't need the user to be able to edit the text. Something like this:
There are basically two ways you could do this. The first is to use auto-layout. I don't have any experience with auto-layout because it is an iOS 6+ feature, but it would probably be worth learning.
The way I usually do it would be be something like:
view1.frame = CGRectMake(20, 20, 200, 200);
view2.frame = CGRectOffset(view1.frame, 0, 20); // same as view1, offset down 20 points
view3.frame = CGRectMake(CGRectGetMinX(view2.frame), CGRectGetMaxY(view2.frame)+10, 80, 80);
These CGGeometry helper functions are quite useful. There are more obscure CGGeometry functions that are less useful, but can be great in some situations: http://nshipster.com/cggeometry/ For the full list, just check out the CGGeometry documentation
The text field looks indeed ugly there. You want an UITextField of type custom with a nice self styled image as backgound. That way you can postion the text as you want. Do the same with the button of type custom, use 4 different images for the 4 states (unchecked, unchecked-pressed, checked and checked-pressed).

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