Increase UIButton's touch effect radius on highlight - iphone

Is there a way to increase UIButton's "glow effect" when Shows Touch on Highlight is enabled? In most of the cases it's fine on the iPhone, but way too small on the iPad. If it's not possible, any ideas how to achieve the desired behavior?
EDIT:
Basically, I'm looking for how to subclass UIButton to add this functionality.

I'll use something like this:
Add a target for button pressed on your button.
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
Here's the method that gets invoked when the button is pressed. You can change the shadowRadius to fit your needs.
- (void) buttonPressed:(id) sender
{
UIButton *button = (UIButton *) sender;
DDLogInfo(#"%# Button Pressed...", button.titleLabel.text);
UIColor *color = [UIColor whiteColor];
button.layer.shadowColor = [color CGColor];
button.layer.shadowRadius = 20.0f;
button.layer.shadowOpacity = 0.9;
button.layer.shadowOffset = CGSizeZero;
button.layer.masksToBounds = NO;
button.backgroundColor = [UIColor whiteColor];
}

You could create an image of the glow effect and add that to the button when its highlighted.

Related

Hit area is only on label of UIButton

I create a UIButton like this:
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0,0,100,100);
The button works, but the hit area is only on the text, not the entire button. I've set the background of the button to be [UIColor clearColor]. What do I need to do to make it so that the entire frame of the button is the hit area?
I suppose I could change the frame of the label to equal the button, but that seems hokey. Is there a better way?
try like this,
UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(0,0,100,100);
button.backgroundColor=[UIColor clearColor];
[button setTitle:#"Set" forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked) forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:button];
The button in question was being built up with layers. What I ended up doing was ensuring the background layer had a solid background color. Simply setting the background of the button to clear did not work in this case.
//set a background color so it is clickable
[layer0 setBackgroundColor: CGCOLORA(0, 1) ];
Setting the opaque property of the UIButton to true worked for me (iOS10)

Create highlighted state background image programmatically for UIButton

I created a UIBarButton programmatically with the following code:
UIButton * rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
[rightButton setFrame:CGRectMake(0, 0, 81, 30)];
[rightButton setBackgroundColor:[UIColor clearColor]];
rightButton.layer.borderColor = [UIColor blackColor].CGColor;
rightButton.layer.borderWidth = 0.5f;
rightButton.layer.cornerRadius = 5.0f;
rightButton.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:12];
[rightButton setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal];
[rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
//set text according to sign in status
if (signIn) {
[rightButton setTitle:#"5 votes left" forState:UIControlStateNormal];
} else {
[rightButton setTitle:#"Sign in" forState:UIControlStateNormal];
}
UIBarButtonItem * rightBarButton = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
self.navigationItem.rightBarButtonItem = rightBarButton;
The obtained button has the desired aspect but now what I need is that when the status of the button is highlighted there should be a gradient effect fading to black to let the user know that he has pressed the button, because right now when I pressed the button, nothing happens to the view so the user has no way to know that he has pressed the button.
I want to explore a choice that does NOT involve setting the background images for the desired states because the text of the button can change dynamically according to the app configurations so I need to do this entirely by code.
Although this won't directly answer your question, it may help. I had to create some graphics for a button dynamically and came up with a method using core graphics to create my button image. It gives me the flexibility to change to appearance parametrically in the code.It draws the button image in an abstract graphics context and then converts the result into an image that I can use for my button. YOu might get enough out of my explanation that you can try it yourself for your needs.
Subclass UIButton and add a CALayer or CAGradientLayer to achieve the highlight effect that you want. Set the initial state of the highlight layer to hidden. Override setHighlighted: with something like:
- (void) setHighlighted:(BOOL)highlight {
highlightLayer.hidden = !highlight;
[super setHighlighted:highlight];
}

Link to webpage from my app

How do I set up a label in Interface Builder to (when clicked) send the user to a website?
What PengOne said. Or progammatically something like this:
UIButton* button = [UIButton buttonWithType: UIButtonTypeCustom];
[button setTitle:#"obliquely.org.uk" forState:UIControlStateNormal];
[[button titleLabel] setFont: [UIFont systemFontOfSize: 16.0]];
[[button titleLabel] setTextAlignment:UITextAlignmentRight];
[button setTitleColor: [UIColor lightGrayColor] forState:UIControlStateNormal];
[button setTitleColor: [UIColor darkGrayColor] forState:UIControlStateHighlighted];
[button setFrame: CGRectMake (100.0, 100.0, 140.0, 16.0 + 4.0)
[button addTarget:self action:#selector(appWebsite) forControlEvents:UIControlEventTouchUpInside];
This gives a gray link that goes darker when the user taps on it. Doing it programmatically can be helpful if you want to position the link carefully and differently depending on orientation / whether you are on iPad or iPhone / other stuff happening on screen. (Though, of course, you can still use IB and just adjust the frame.)
And then add a method a bit like this:
- (void) appWebsite;
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://obliquely.org.uk/blog/app"]];
}
Add a button,
IBOutlet UIButton *myButton;
and declare an action
-(IBAction)goToWebSite;
Set the button target to the action in the IB. In the .m file, define the action:
-(IBAction)goToWebSite {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.mywebpage.com"]];
}
Use a UITextView to hold the URL text. It will automatically be clickable and will take the user there when clicked. You can give the textView a clear background so it looks just like a label or whatever you want.

Why doesn't this UIButton show its text label?

Everything about this UIButton renders great except the text that's supposed to be on it. NSLog demonstrates that the text is in the right place. What gives?
UIButton *newTagButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[newTagButton addTarget:self action:#selector(showNewTagField) forControlEvents:UIControlEventTouchUpInside];
newTagButton.titleLabel.text = #"+ New Tag";
NSLog(#"Just set button label to %#", newTagButton.titleLabel.text);
newTagButton.titleLabel.font = [UIFont systemFontOfSize:17];
newTagButton.titleLabel.textColor = [UIColor redColor];
CGSize addtextsize = [newTagButton.titleLabel.text sizeWithFont:[UIFont systemFontOfSize:17]];
CGSize buttonsize = { (addtextsize.width + 20), (addtextsize.height * 1.2) };
newTagButton.frame = CGRectMake(x, y, buttonsize.width, buttonsize.height);
[self.mainView addSubview:newTagButton];
There are a set of APIs on UIButton that should be used to change those properties.
The titleLabel can and will be changed by the UIButton internally.
[button setTitle:title forState:state];
[button setTitleColor:color forState:state];
[button setTitleShadowColor:color forState:state];
You should always set these properties through these methods (when available) rather than touching the titleLabel directly. For fonts you can change it on the titleLabel directly since they don't provide a method on UIButton.

Is there an way to make an invisible UIButton that will still "be there" and catch touch events for my UIImageView?

I thought to be clever and just put an transparent UIButton over an UIImageView with the exact frame size, so that I can wire it up easily with any event I like, for example TouchUpInside, and make it call a action method of an view controller when the user touches it. Well, it works until alpha is below 0.1f. If I do 0.01f, it will not work. So to get it work, when looking a long time on the screen, you'll see that 0.1f of alpha shining through. And that's totally disgusting ;)
It seems like iPhone OS trys to be clever and won't catch events on the button if it's visually not there. Any idea how to solve that?
Sure I could make a subclass of UIImageView and implement touchesBegan:... etc., but it doesn't feel really elegant. I mean...when I want to hyperlink an image on the web, I would never want create my own HTML element for that image, just to wire it up to an url when it's clicked. That just doesn't make a lot of sense to me.
You should be able to set the button's 'Type' to Custom in Interface Builder, and it will not display any text or graphical elements over the UIImageView. This way, you don't need to adjust the alpha. If the view is built from code, use:
button = [UIButton buttonWithType:UIButtonTypeCustom];
In addition to UIButtonTypeCustom, I set the button text colors to the following:
[button setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
[button setTitleShadowColor:[UIColor clearColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor clearColor] forState:UIControlStateHighlighted];
[button setTitleShadowColor:[UIColor clearColor] forState:UIControlStateHighlighted];
The best way of doing this is:
myButton.hidden = YES;
You can't use the buttonType property because it is a read only property. Only way to use it is when creating your button dynamically.
i also beleive you can assign an image to a button.
The image can take up the entire frame and can also have no other artifacts of the buttone if you set it up right.
check out the Property
UIButtonInstance.currentImage
That way you are not hogging your resources with elements that are essentially already there.
You can hide a button (or any object) and keep it active by adding a mask to its layer. The button will be invisible but will still catch events.
let layer = CAShapeLayer()
layer.frame = .zero
myButton.layer.mask = layer
Jasons answer above is nearly correct, but setting the button type is not possible. So to programmatically create an empty button, use this code:
UIButton* myButton = [UIButton buttonWithType:UIButtonTypeCustom];
myButton.frame=frame;
[self.view addSubview:myButton];
This is what i did but with using a subclass of UIButton which i later found out should not be subclassed as per the net. My subclass was called Points
Points *mypoint=[Points buttonWithType:UIButtonTypeCustom];
then if you have an image you want to add to the button :
[mypoint setImage:imageNamed:#"myimage"] forstate: UIControlStateNormal];
if you dont add this image then the button will be invisible to the user but should respond to touch. Thats how i created a hotspot on my imageView inorder to have it respond to user interaction.
It's the only way I found...
[yourButton setImage:[UIImage imageNamed:#"AnEmptyButtonWithTheSameSize.png"] forState:UIControlStateNormal];
Take care of the image. It must be .png
Custom UIButtons respond to user interactions unless their alpha is set to 0. Put a custom UIButton on top of your imageView and connect to buttonPressed action. I have also set an additional highlighted image for my UIView, now it really behaves like a UIButton. First I have defined a duration for the UIView for staying highlighted:
#define HIGHLIGHTED_DURATION 0.1
Then set the image view highlighted if the button is pressed and start a timer to keep it highlighted for that duration. Do not forget to set the highlighted image for your imageview.
- (IBAction)buttonPressed:(id)sender {
[_yourImageView setHighlighted:YES];
_timer = [NSTimer scheduledTimerWithTimeInterval:HIGHLIGHTED_DURATION
target:self
selector:#selector(removeHighlighted)
userInfo:nil
repeats:NO];
}
And simply undo highlighting when the timer finishes:
-(void) removeHighlighted{
_yourImageView.highlighted = NO;
}
lazyImageView = [[UIImageView alloc] init];
button=[[UIButton alloc]init];
[UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(aMethodForVideo:)
forControlEvents:UIControlEventTouchUpInside];
[button setBackgroundImage:[UIImage imageNamed:#"BackTransparent.png"] forState:UIControlStateHighlighted];
[button setTitle:#"" forState:UIControlStateNormal];
lazyImageView.frame=CGRectMake(x, y, w, h);
button.frame=CGRectMake(x, y, w, h);
Set frame of button and Image both have same frame .I use this code and working fine.Also set button background image forState:UIControlStateHighlighted so when you click on that when you see the click effect.
I managed to do it using the following code.
If the iPad is landscape the button will be located in the top right of the screen.
UIButton *adminButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
adminButton.frame = CGRectMake(974.0f, 0.0f, 50.0f, 50.0f);
[adminButton setBackgroundColor:[UIColor clearColor]];
[adminButton setTag:1];
[adminButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:adminButton];
Pressing the 'adminButton' will run the following function:
- (void)buttonPressed:(id)sender {
int buttonId = ((UIButton *)sender).tag;
switch(buttonId) {
case 1:
NSLog (#"Admin button was pressed");
break;
case 2:
//if there was a button with Tag 2 this will be called
break;
default:
NSLog(#"Key pressed: %i", buttonId);
break;
}
}