I am unable to add button on UIView. I have UIView In which I want to add UIButton. Here is my code which I am trying to implement.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setMultipleTouchEnabled:NO];
path = [UIBezierPath bezierPath];
[path setLineWidth:1.0];
_button = [UIButton buttonWithType:UIButtonTypeCustom];
[_button setTitle:#"" forState:UIControlStateNormal];
_button.userInteractionEnabled=YES;
_button.frame =CGRectMake(50, 130, 100, 100);
_button.backgroundColor =[ UIColor redColor];
[_button addTarget:self
action:#selector(buttonClicked)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_button];
}
return self;
}
Your button is being added to the view. I just tried with your code line by line and I could see it. I think problem is in your UIView frame. Probably you are not seeing it because it is crossing the boundary of your super UIView.
Instead of assigning to __button, make a local UIButton object and work with it. After the local button has been added to the view, assign it to _button.
Related
I'm creating custom UIView that contains two UILabels and UIButton so I created a subclass to make this possible.
Now the process looks like:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
self.backgroundColor = [UIColor whiteColor];
self.settingsButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size.width - 2 * margin, frame.size.height - titleHeight - dateHeight, buttonSize, buttonSize)];
[self.settingsButton setImage:[UIImage imageNamed:#"settings_icon"] forState:UIControlStateNormal];
[self addSubview:self.settingsButton];
[self.settingsButton addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
return self;
}
Button appears on UIView but it is not clickable. I tried to set self.userInteractionEnabled = YES; and a couple things but still no result :(
This is the most dumb mistake I've ever made. Transparent UINavigationBar was blocking the touch.
Working off of other Stack Overflow answers, I have managed to come up with the code below:
(in my homescreen.m file)
UIButton *GCButton;
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
//add button
[self addGameCenterButton];
}
return self;
}
-(void)addGameCenterButton
{
GCButton = [[UIButton alloc]initWithFrame:CGRectMake(50, 20, 30, 30)];
[GCButton setBackgroundColor:[UIColor orangeColor]];
[GCButton setTitle: #"My Button" forState:UIControlStateNormal];
[GCButton setTitleColor: [UIColor blueColor] forState:UIControlStateNormal];
[GCButton.layer setBorderWidth:1.0f];
[GCButton.layer setBorderColor:[UIColor blueColor].CGColor];
//adding action programatically
[GCButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:GCButton];
}
-(void)buttonClicked:(UIButton*)sender
{
NSLog(#"you clicked on button %ld", (long)sender.tag);
}
As of right now, I see nothing on my screen. Is there anything else I need to add in my .m or .h files to make the button work?
From the comments of your question, I'm assuming you are using SpriteKit. In a GameScene, unfortunately, you cannot use UIButtons normally.
To create buttons for your scene, please check the answers in the link below:
Setting up buttons in SKScene
I am programmatically creating buttons in a view inside UIScrollView. I also have programmatically created UITextField. I can select and enter data into the text fields all day long. But I cannot get any sign the buttons are being touched. I can add them to the main view and they work. But when added to the view inside the UIScrollView, they are lost in another dimension. I've read plenty of info about setting userInteraction, delayContentTouches, and intercepting via gestureRecognizer. The last might be related to my problem. I return NO via [touch.view isDescendantOfView:self.myScrollViewName]. I can't get it to trigger via [touch.view isKindOfClass:[UIButton class]]. Which makes me think I have a more fundamental error I am missing?
related:
https://stackoverflow.com/a/6825839/4050489
edited to add button code per request:
self.myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.myButton.frame = myButtonFrame;
self.myButton.enabled = interface.isActive;
self.myButton.userInteractionEnabled = YES;
self.myButton.exclusiveTouch = YES;
self.myButton.backgroundColor = [UIColor greenColor];
//self.myButton. = YES;
self.myButton.layer.borderWidth=1.0f;
self.myButton.layer.borderColor=[[UIColor blackColor] CGColor];
self.myButton.layer.cornerRadius = 10;
[self.myButton setTag:interface.tag];
[self.myButton setTitle:interface.Name forState:UIControlStateNormal];
[self.myButton addTarget:self action:#selector(navigatePartButtons:) forControlEvents:UIControlEventTouchUpInside];
[self.myButton setEnabled:YES]; //error check
[self.partSetupView addSubview:self.myButton];
partSetupView is a UIView in the UIScrollView.
Try this sample Code:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *myScroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 100, 300, 300)];
myScroll.backgroundColor = [UIColor redColor];
[self.view addSubview:myScroll];
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 300, 200)];
myView.backgroundColor = [UIColor yellowColor];
[myScroll addSubview:myView];
UIButton *myButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 300, 100)];
myButton.backgroundColor = [UIColor blackColor];
[myView addSubview:myButton];
[myButton addTarget:self action:#selector(btnClick) forControlEvents:UIControlEventTouchDown];
}
-(void)btnClick{
NSLog(#"Button Click");
}
#end
I'm trying to add multiple subview programmatically, but my buttons inside those subviews are not working. The buttons were also added as subviews programmatically.
Here's the code, hopefully will explain more about what I mean.
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
[self setBackgroundColor:[UIColor clearColor]];
// UIView container of selected image with comment button.
UIView *containerOfSelectedImage = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 0, 350)];
NSLog(#"%f", self.frame.size.width);
// image view of selected photo by user.
UIImageView *userImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"nature_01.jpg"]];
[userImage setFrame :CGRectMake(0, 0, 340, 300)];
// comment button with action of recodering user's comment.
UIButton *commentButton = [UIButton buttonWithType:UIButtonTypeCustom];
//[commentButton setBackgroundColor : [UIColor clearColor]];
float y = userImage.frame.size.height + 5.0f;
[commentButton setFrame : CGRectMake(32.0f, y, 24.0f, 24.0f)];
[commentButton addTarget:self action:#selector(audioRecordAction) forControlEvents:UIControlEventTouchDown];
[commentButton setImage:[UIImage imageNamed:#"comments-24.png"] forState:UIControlStateNormal];
[containerOfSelectedImage addSubview:userImage];
[containerOfSelectedImage addSubview:commentButton];
[self addSubview:containerOfSelectedImage];
[self addSubView:self.commentContainerView];
return self;
You need to increase the frame of the containerOfSelectedImage. Currently the width is 0.
The containerOfSelectedImage's frame has to be big enough so the button fits inside it. If the button is outside that frame it will show up but you can't touch him.
To debug this issues you can use a tool like Reveal App. If any of your buttons is outside the frame of the parent then the touch will not be detected.
Change [commentButton addTarget:self action:#selector(audioRecordAction) forControlEvents:UIControlEventTouchDown]; to [commentButton addTarget:self action:#selector(audioRecordAction) forControlEvents:UIControlEventTouchUpInside];
I want to draw a line between two UILabels when i tap or hold both of them at the same time with code, i have no idea how to do this, it will be most appreciated if anyone has an advice , it will be most appreciated
This is how I would do it. My answer is tested btw...
To manage the tappable labels I would create my own label called LabelControl that extends UIControl. This custom control is going to have a UILabel (read-only for simplicity) as a subview. By doing this we will be able to add the Target-Action events UIControlEventTouchDown and UIControlEventTouchUpInside.
Here is the custom label:
The .h file:
#interface LabelControl : UIControl
#property (nonatomic, retain, readonly) UILabel *theLabel;
#end
The .m file:
#implementation LabelControl
#synthesize theLabel = _theLabel;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_theLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
_theLabel.backgroundColor = [UIColor clearColor];
_theLabel.userInteractionEnabled = NO;
[self addSubview:_theLabel];
}
return self;
}
-(void)dealloc {
[_theLabel release];
[super dealloc];
}
Then for the "line" that you want to draw, I would use a UIView because that way you could just use it's hidden property to hide/show the line. Add this code inside your ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.label1 = [[[LabelControl alloc] initWithFrame:CGRectMake(60, 50, 200, 40)] autorelease];
self.label1.theLabel.text = #"Hello";
self.label1.userInteractionEnabled = YES;
self.label1.backgroundColor = [UIColor blueColor];
[self.label1 addTarget:self action:#selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[self.label1 addTarget:self action:#selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.label1];
self.label2 = [[[LabelControl alloc] initWithFrame:CGRectMake(60, 150, 200, 40)] autorelease];
self.label2.theLabel.text = #"World";
self.label2.userInteractionEnabled = YES;
self.label2.backgroundColor = [UIColor purpleColor];
[self.label2 addTarget:self action:#selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[self.label2 addTarget:self action:#selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.label2];
//the position of the line is hard-coded. You will have to modify this yourself
self.theLine = [[UIView alloc] initWithFrame:CGRectMake(60, 120, 200, 3)];
self.theLine.backgroundColor = [UIColor blueColor];
self.theLine.hidden = YES;
[self.view addSubview:self.theLine];
}
-(void)showOrHideLine {
if (self.label1.selected && self.label2.selected) {
NSLog(#"Both are selected");
self.theLine.hidden = NO;
} else {
self.theLine.hidden = YES;
}
}
-(void)touchDown:(id)sender {
//When any of the custom label gets the touch down event set the `selected` property
//to YES. (This property is inherited form `UIControl`
NSLog(#"Touch down");
LabelControl *labelControl = (LabelControl*)sender;
labelControl.selected = YES;
[self showOrHideLine];
}
-(void)touchUp:(id)sender {
//When any of the custom label gets the touch up event set the `selected` property
//to NO. (This property is inherited form `UIControl`
NSLog(#"Touch Up");
LabelControl *labelControl = (LabelControl*)sender;
labelControl.selected = NO;
[self showOrHideLine];
}
Let me know if you have any questions. Hope this helps!
I am going to outline it and give you some code (untested) but you have some work to make the full effect work.
Programtically, you could subclass UIButton. Inside your new subclass, put your touch recognition methods. Call it something like "customUIButton".
From your main view controller, create two instances of your UIButton and add them as subviews
customUIButton *Label1 = [[customUIButton alloc] init];
[Label1 setTitle:#"Your First Label" forState:UIControlStateNormal];
[Label1 addTarget:self action:#selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Label1];
customUIButton *Label2 = [[customUIButton alloc] init];
[Label2 setTitle:#"Your Second Label" forState:UIControlStateNormal];
[Label2 addTarget:self action:#selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Label1];
When you push the buttons, it will try to call the method "itemClicked". Make that method and receive (id)sender... - (void)itemClicked: (id)sender { Put some logic in there to indicate that the button is being pushed. You know which button by referring to the sender that was sent.
Also in your view controller, go to the DrawRect method and put in the drawing logic.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 3.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextMoveToPoint(context, Label1.center.x, Label1.center.y);
CGContextAddLineToPoint(context, Label2.center.x, Label2.center.y);
CGContextStrokePath(context);
CGContextRestoreGState(context);
Put this in an "if statement" so that if both buttons have focus, it will be drawn (else skip the drawing code).
How about placing a line in IB using an Image View. Hide the Image View in your viewDidLoad method. Then, whenever the user taps one of the the UILabels, unhide the Image View holding your line. It may be tricky depending on your experience with Objective-C to detect touches on a UILabel. If it is, you can place invisible buttons over each label and that should do the trick for you. For more info about detecting touches on UILabels, check this link:
Handling Touch Event in UILabel and hooking it up to an IBAction