UIButton - changing frame alters response to touches - iphone

I have a UIButton. I found that when I moved it, it no longer responded to touches. Let me explain in detail how I determined this: when I shift a 100pixel width button by 50 pixels to the right, only the left half responded to my finger tapping it.
How do I tell the button "update your touches checker" when I dynamically change the frame of it? I am changing the frame in code, NOT in xib.
Initialization:
MATCGlossyButton *repeat = [[MATCGlossyButton alloc] init];
[repeat addTarget:self action:#selector(repeatPressed:) forControlEvents:UIControlEventTouchUpInside];
[repeat setTitle:#"Repeat" forState:UIControlStateNormal];
repeat.buttonColor = [UIColor brownColor];
repeat.backgroundColor = [UIColor clearColor];
repeat.cornerRadius = 20;
repeat.frame = CGRectMake(200,208,105,50);
And then later on:
repeat.frame = CGRectMake(265, 208, 105, 50);

Is it possible you are moving the button beyond the bounds of its parent view? Even if clipping is off, touches aren't propagated outside of a view.
An easy way to visualise the borders of your views is to do the folowing:
#import <QuartzCore/QuartzCore.h>
[...]
view.layer.borderWidth = 1;
view.layer.borderColor = [UIColor redColor].CGColor;

Related

How to remove the saw tooth of UIView when using Quartz?

I want to add a head button to a view with some white space around it. My code is just like this:
// head button
UIButton * btnHead = [UIButton buttonWithType:UIButtonTypeCustom];
btnHead.frame = CGRectMake(0, 0, self.frame.size.width - property.userhead_cell_space / 2, self.frame.size.width - property.userhead_cell_space / 2);
btnHead.clipsToBounds = YES;
btnHead.layer.cornerRadius = btnHead.bounds.size.width / 2;
btnHead.layer.borderColor = [UIColor whiteColor].CGColor;
btnHead.layer.borderWidth = (isPad?4.0f:2.0f);
btnHead.layer.contentsScale = [[UIScreen mainScreen] scale];
btnHead.layer.backgroundColor = [UIColor whiteColor].CGColor;
[btnHead addTarget:self action:#selector(clickHead:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btnHead];
But alway it has some saw tooth around it . It may only one pixel. But it looks very terrible . Just like this:
Does anybody has some tip to remove the black saw tooth ?
Way late to the party but from past experience this is a bug with corner radius and borders. I've tried using it to create circular borders around views and have noticed similar bleeding.
One workaround is to create a view for the border and then a slightly inset view for the image.
UIView* border = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
border.backgroundColor = UIColor.whiteColor; // border color
border.layer.cornerRadius = border.bounds.size.width / 2;
border.layer.masksToBounds = YES;
// inset by the desired border width
UIImageView* image = [[UIImageView alloc] initWithFrame:CGRectInset(border.bounds, 2, 2)];
image.image = someImage;
image.layer.cornerRadius = image.bounds.size.width / 2;
image.layer.masksToBounds = YES;
[border addSubview:image];
[self addSubview:border];
If you want to avoid multiple views, you could add an additional background layer to the image view's layer for the border. That would need to have it's bounds negatively inset so that it drew around the image.

Subview appears underneath superviews layer.border?

I have a UIView in which I define it's border in the following manner:
self.layer.borderColor = [UIColor blackColor].CGColor;
self.layer.borderWidth = 3;
I attach a subview to this UIView, and when I move the subview over the border, it goes underneath it. Is this the intended behavior? Is there anyway to make the subview go on top of it?
According to the Apple specification: It is composited above the receiver’s contents and sublayers.
So, the border will always be above of all your subviews, even if you bring your subview to the front and so on.
So I make a background view to fake the border.
E.g.:
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
backgroundView.backgroundColor = [UIColor blackColor];
backgroundView.clipsToBounds = NO;
UIView *bView = [[UIView alloc] initWithFrame:CGRectInset(backgroundView.bounds, 3, 3)];
bView.backgroundColor = [UIColor redColor];
UIView *cView = [[UIView alloc] initWithFrame:CGRectMake(-50, -50, 100, 100)];
cView.backgroundColor = [UIColor yellowColor];
[bView addSubview:cView];
[backgroundView addSubview:bView];
[self.window addSubview:backgroundView];
and the effect:
Depending on your view structure, it might be easier to add the subview to the parent of your main view. It can then overlap the main view and will overlay the border as you requested.
Did you try setting the superview's 'clipsToBounds' property to YES? This is set to NO by default for performance reasons, but setting it to yes might give you the effect you are looking for.
Insert layer at specific position that suits you:
self.layer.insertSublayer(sublayer, at: 0)

Rounding color around borders of a button

I've got a little problem as seen below:
The cell has a background color, and the button doesn't. Still, it doesn't give me rounded edges, but corners. How can I fix that?
UIButton *meerKnop = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[[meerKnop layer] setCornerRadius:8.0f];
meerKnop.backgroundColor = [UIColor whiteColor];
meerKnop.frame = CGRectMake(11.0, (60.0 + (teller * 52.5)), 299.0, 50.0);
...
[meerKnop addSubview:locationLabel];
...
[meerKnop addSubview:categoryLabel];
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipe.direction = UISwipeGestureRecognizerDirectionRight;
[meerKnop addGestureRecognizer:swipe];
[swipe release];
[meerKnop addTarget:self action:#selector(alertPressed:) forControlEvents:UIControlEventTouchUpInside];
meerKnop.tag = incId;
[cell addSubview:meerKnop];
Try setting the corner radius of the layer of the button.
[button.layer setCornerRadius:10];
Remember to import if you are using layer property
Also, use:
[[button layer] setMasksToBounds:YES];
With this code the layer gets a corner radius of 10.0 and the -setMasksToBounds: tells the button’s layer to mask any layer content that comes below it in the layer tree. This is necessary in order for the layer to mask off the rounded corners.
UIButton *meerKnop = [UIButton buttonWithType:UIButtonTypeRoundedRect];
Change this to:
UIButton *meerKnop = [UIButton buttonWithType:UIButtonTypeCustom];
Edited:
UIButton *meerKnop = [UIButton buttonWithType:UIButtonTypeCustom];
[[meerKnop layer] setCornerRadius:8.0f];
meerKnop.backgroundColor = [UIColor redcolor];
meerKnop.frame = CGRectMake(11.0, (60.0 + (teller * 52.5)), 299.0, 50.0);
show me where the big white rectangle is appearing? (I hope u have cleared the cell background color).
change the background colour of the button to same as that of cell.. it will take care of the rounded edges as there colour will become same as that of the background. sry i new.. i can think of this way only at the moment.. Hope it helps..

Dynamic Button Layout without hard coding positions

I would like to implement a view (it will actually be going into the footer of a UITableView) that implements 1-3 buttons. I would like the layout of these buttons (and the size of the buttons themselves) to change depending on which ones are showing. An example of almost the exact behavior I would want is at the bottom of the Info screen in the Contacts application when you are looking at a specific contact ("Add to Favorites" disappears when it is clicked, and the other buttons expand to take up the available space in a nice animation).
As I'm running through the different layout scenarios, I'm hard coding all these values and I just think... "this is NOT the way I'm supposed to be doing this."
It even APPEARS that Interface Builder has some features that may do this for me in the ruler tab, but I'll be darned if I can figure out how they work (if they work) on the phone.
Does anyone have any suggestions, or a tutorial online that I could look at to point me in the right direction?
Thanks much.
You could take a look at
Stanford cs193p classes
I think there is a demo in one of the lessons/example where they programaticaly set the autoresize of the buttons and some other where they animate the view.
you can also make the view set dynamically the width of each of its subview to (ownWidth/numberofSubView),the same for the positon of each elements.
[edit] like that ? it's not "dynamic" yet, but you've got the idea
you can increase/decrease numberOfbuttons when "adding/removing" a button then reset the new frame of all the subviews
- (void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor lightGrayColor];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
int numberOfbuttons = 2;
CGFloat buttonsLegth = (-20+view.bounds.size.width)/numberOfbuttons-20;
for(int i=0;i<numberOfbuttons;i++){
CGRect buttonFrame = CGRectMake(0, 0, buttonsLegth, 37);
buttonFrame.origin.x = (buttonFrame.size.width+20)*i + 20.0;
buttonFrame.origin.y = 20.0;
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // Autoreleased
button.frame = buttonFrame;
[button setTitle:#"Done" forState:UIControlStateNormal];
[view addSubview:button];
}
self.view = view;
[view release];
}
hi remove all buttons in view and add again using this method...
you have to pass number of buttons and a UIView in which you want to add these buttons
-(void)addButtons:(int)numberOfButtons ToView:(UIView *)containerView;
{
CGRect containerRect = containerView.frame;
CGFloat padding = 5.0;
CGFloat width = (containerRect.size.width - (padding*numberOfButtons+1))/numberOfButtons;
for (int i = 1; i<=numberOfButtons; i++)
{
UIButton * btn = [[[UIButton alloc] initWithFrame:CGRectMake(i*padding+width, 0, width, containerRect.size.height)]autorelease];
//set Button Properties like Target,backColor,Title,,,,etc MUST SET TAG TO ACCESS THEM IN CLICK METHOD IF YOU ARE USING SAME SELECTOR FOR ALL BUTTONS.
[containerView addSubview:btn];
}
}
Try this and have fun......

Adding multiple UIButtons to an UIView

I've added some buttons to an UIView (via addSubview) programmatically. However, they appear as overlays (so that I always see the last button only). How do I add new buttons below existing buttons?
Regards
you can offset the button like this
int newX = previousButton.frame.origin.x + previousButton.frame.size.width ;
int newY = previousButton.frame.origin.y ;
and either set the frame for new button when you create it:
[[UIButton alloc] initWithFrame:CGRectMake(newX,newY,100,100)];
or set the frame later
newButton.frame = CGRectMake(newX,newY,100,100);
Set the UIView's frame origin to layout the UIButtons in the locations you wish:
CGRect buttonFrame = button.frame;
buttonFrame.origin = CGPointMake(100.0f, 100.0f);
button.frame = buttonFrame;
view.addSubview(button);
You can either use the insertSubview:atIndex method or insertSubview:belowSubview of your view.
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,100,100)];
[myView insertSubview:myButton belowSubview:previousButton];
OR
[myView insertSubview:myButton atIndex:0];
Thanks for your answers guys.
I did the (horizontal) align with this code:
if([myContainer.subviews lastObject] == nil){
NSLog(#"NIL");
[myContainer insertSubview:roundedButton atIndex:0];
}else{
[myContainer insertSubview:roundedButton belowSubview:[tagsContainer.subviews lastObject]];
}
It works technically, but still overlays the buttons. I have to find a way, how to not overlay them...