I have made a UIView which contains a table and some buttons. This view is called by a UIViewController which is called by a tab-bar controller. There is no IB involved.
When the view comes up it only has the outlines of the objects. e.g. the following button comes out without its label:
brect = CGRectMake(80, 330, 60, 27);
centern=CGPointMake(CGRectGetMidX(brect), CGRectGetMidY(brect) );
UIButton * button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setFrame:brect];
[button2 setCenter:centern];
[button2 setTitle:#"Delete" forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(deldate:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button2];
As soon as I make the first touch everything appears as it should.
What am I doing wrong?
[self.view addSubview:button2];
self is an instance of UIViewController.
self contain a view. you should add you UIButton to view, not viewController.
Related
I have a UIViewController called MyViewController. MyViewController's view has an UIButton called MyFirstButton as a subview. Then MyViewController's view adds another subview called MySubView. MySubView is placed directly over MyFirstButton, so MyFirstButton isn't seen. MySubView in its turn has an UIButton called MySecondButton as a subview.
The issue is - if MySecondButton's frame overlaps MyFirstButton's frame, then MySecondButton doesn't respond.
I tried to fix it by setting userInteractionEnabled to NO for MyViewController's view and YES for MySubView, but it didn't help. The button still not responding. How do i enable a button which is located over another?
You cant use the action for that particular MyFirstButton which is under MySecondButton... I dnt think this can be done .. what you can actually do is hide MySecondButton on its click to reveal the MYFirstButton and then on the MYFirstButton click have its action performed and reveal the MYSecondButton again on top of the first one :) likewise play hidden with the subviews 2...
try this,
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *firstButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[firstButton setTitle:#"first" forState:UIControlStateNormal];
firstButton.frame=CGRectMake(40, 70, 80, 80);
[firstButton addTarget:self action:#selector(firstButtonClicked) forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:firstButton];
UIView *view=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
[firstButton addSubview:view];
UIButton *secondButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[secondButton setTitle:#"second" forState:UIControlStateNormal];
secondButton.frame=CGRectMake(0, 0, 80, 80);
[secondButton addTarget:self action:#selector(secondButtonClicked) forControlEvents: UIControlEventTouchUpInside];
[view addSubview:secondButton];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)firstButtonClicked {
NSLog(#"first");
}
-(void)secondButtonClicked {
NSLog(#"second");
}
I have a Storyboard View Controller (with my own custom sub class) of which I have a initWithCoder custom method, where I want to popular the view with my own custom objects (I want to maintain the flexibility of doing this programmatically.
Code works fine until [self.view addSubview:button]; is called, then it crashes with: "Could not load NIB in bundle".
All I wanted to do was add a UIButton on my view...
- (id)initWithCoder:(NSCoder*)aDecoder
{
if(self = [super initWithCoder:aDecoder])
{
[self initLoginForm];
}
return self;
}
-(void)initLoginForm
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100, 170, 100, 30);
[button setTitle:#"Login..." forState:UIControlStateNormal];
[button addTarget:self action:#selector(handleLoginAttempt) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
how about putting the button in the viewDidLoad method, then add it in the initLoginForm.
Something like this:
-(void)viewDidLoad {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100, 170, 100, 30);
[button setTitle:#"Login..." forState:UIControlStateNormal];
[button addTarget:self action:#selector(handleLoginAttempt) forControlEvents:UIControlEventTouchUpInside];
}
-(void)initLoginForm {
[self.view addSubview:button];
}
or add it in the viewDidLoad then hide it, then in the initLoginForm show it.
I want to add a button in a UITableViewCell. This is my code: `
if (indexPath.row==2) {
UIButton *scanQRCodeButton = [[UIButton alloc]init];
scanQRCodeButton.frame = CGRectMake(0.0f, 5.0f, 320.0f, 44.0f);
scanQRCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
scanQRCodeButton.backgroundColor = [UIColor redColor];
[scanQRCodeButton setTitle:#"Hello" forState:UIControlStateNormal];
[cell addSubview:scanQRCodeButton];
}`
Now, when I run the app, I see only a blank row ! Any ideas ?
While it's natural to put it in the contentView of the cell, I'm fairly certain that is not the problem (actually, in the past, I've never had subviews displayed correctly in the contentView, so I've always used the cell).
Anyway, the problem involves the first three lines of when you start creating your button. The first two lines are fine, but the code stops working with:
scanQRCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
buttonWithType: is actually a convenience method to create a button (it's like a compact alloc-init). Therefore, it actually "nullifies" your past two lines (you basically created the button twice). You can only use either init or buttonWithType: for the same button, but not both.
UIButton *scanQRCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
scanQRCodeButton.frame = CGRectMake(0.0f, 5.0f, 320.0f, 44.0f);
scanQRCodeButton.backgroundColor = [UIColor redColor];
[scanQRCodeButton setTitle:#"Hello" forState:UIControlStateNormal];
[cell addSubview:scanQRCodeButton];
This will work (note that you can use cell.contentView if you wanted). In case you're not using Automatic Reference Counting (ARC), I would like to mention that you don't have to do anything in term of memory management, because buttonWithType: returns an autoreleased button.
UIButton *deletebtn=[[UIButton alloc]init];
deletebtn.frame=CGRectMake(50, 10, 20, 20);
deletebtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[deletebtn setImage:[UIImage imageNamed:#"log_delete_touch.png"] forState:UIControlStateNormal];
[deletebtn addTarget:self action:#selector(DeleteRow:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:deletebtn];
or
// Download class and import in your project UIButton+EventBlocks
UIButton *deletebtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[deletebtn setFrame:CGRectMake(170,5, 25, 25)];
deletebtn.tag=indexPath.row;
[deletebtn setImage:[UIImage imageNamed:#"log_delete_touch.png"] forState:UIControlStateNormal];
[deletebtn setOnTouchUpInside:^(id sender, UIEvent *event) {
//Your action here
}];
[cell addSubview:deletebtn];
You want to add any custom UI elements to the cell's contentView.
So, instead of [cell addSubview:scanQRCodeButton];
do [cell.contentView addSubview:scanQRCodeButton];
Try adding [cell.contentView addSubview:scanQRCodeButton]; or if you want the button to the left side look at my question at the answer, to move the textLabel to the side. If you want the button to the right then just set it as your accesoryView like this cell.accesoryView = scanQRCodeButton;.
Method setTitle does not work in my code, so I have set by using
[UIButton.titleLabel setText:#""]
instead of using setTitle method.
Please try again with following code:
[scanQRCodeButton.titleLabel setText:#"Hello"];
Then it would work well.
I am creating a custom button and putting it in my table's footer view but the button is going way out from the right corner.
What is wrong here!?!
Here is my code and output image:
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[aButton setTitleColor:[UIColor colorWithWhite:0.0 alpha:0.56] forState:UIControlStateDisabled];
[aButton setBackgroundImage:[[UIImage imageNamed:#"test.png"] stretchableImageWithLeftCapWidth:kButtonSliceWidth topCapHeight:0] forState:UIControlStateNormal];
[aButton setTitle:#"Click me" forState:UIControlStateNormal];
[aButton.titleLabel setFont:[UIFont boldSystemFontOfSize:kFontSize14]];
[aButton setFrame:CGRectMake(10.0, 15.0, 300.0, 44.0)];
[self.tableView setTableFooterView:aButton];
I added the button in the UIView and then set the tableFooterView to this UIView object and it worked. We cannot directly put UIButton as tableFooterView.
Try doing like this. Set IBOutlet UIView *footerView; and synthesize it. Add it as a subview using the method-
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if(footerView == nil) {
//allocate the view if it doesn't exist yet
footerView = [[UIView alloc] init];
//create the button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(10, 3, 300, 44)];
//set title, font size and font color
[button setTitle:#"Click Me" forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont boldSystemFontOfSize:18]];
//set action of the button
[button addTarget:self action:#selector(clickPressed:)
forControlEvents:UIControlEventTouchUpInside];
//add the button to the view
[footerView addSubview:button];
}
//return the view for the footer
return footerView;
}
One important addition to Legolas' fine answer: You'll need to implement the tableView delegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
foot 50;
}
This was driving me nuts because the button (or, in my case, buttons) were not responding to the touch event. Adding the delegate method made it all better. :-)
I'm trying to use dynamic buttons created via code (no IB) in my project and they appear where and how I want them but they don't fire their actions.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(475, 302, 49, 58);
[button1 setTitle:#"1"
forState:(UIControlState)UIControlStateNormal];
[button1 addTarget:self
action:#selector(goToFirstTrailer)
forControlEvents:(UIControlEvents)UIControlEventTouchDown];
[myImageView addSubview:button1];
-(void)goToFirstTrailer {
[self startAnimator:#"OutsideToTrailer1_" forNumFrames:60];
}
The imageView this is placed on has buttons and User Interaction Enabled On.
Any light you can shed would be much appreciated.
I think you have the wrong signature of the action method change that line to
-(void) goToFirstTrailer:(id)sender {
and where you set the action to
[button1 addTarget:self action:#selector(goToFirstTrailer:) forControlEvents:....
Important is the colon after the message name because I changed the action method signature to include the sender.
Edit I wrote a small sample project with just an imageView in the MainWindow.xib and created a button programmatically as follows
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectMake(0.f, 0.f, 50.f, 50.f);
[button1 setTitle:#"1"
forState:(UIControlState)UIControlStateNormal];
[button1 addTarget:self
action:#selector(goToFirstTrailer:)
forControlEvents:(UIControlEvents)UIControlEventTouchDown];
imageView.userInteractionEnabled = YES; // <--- this has to be set to YES
[imageView addSubview:button1];
[self.window makeKeyAndVisible];
return YES;
}
It is quick and dirty and yes, I am misusing the application delegate as the view controller. I know it is bad.
Here is the action method
- (void) goToFirstTrailer:(id)sender {
imageView.backgroundColor = [UIColor redColor];
}
Setting the userInteractionEnabled property on the parent imageView makes the difference. With it set to NO which is the default, no events are routed to the button.
If myImageView is a UIImageView object, adding a subview to it (like UIButton) only displays the image that object is represented by. If you add that UIButton as a subview of a UIView, it should work perfectly. Try adding an auxiliary UIView to your UIImageView and then add your button to a subview of the new auxiliary UIView, that should solve your problem.
This works fine for me. Note that I changed the event to UIControlEventTouchUpInside to allow the button press down state to be visible first.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(20,400,88,35); //The position and size of the button (x,y,width,height)
[btn setTitle:#"Quit" forState:UIControlStateNormal];
[btn addTarget:self
action:#selector(showAbout)
forControlEvents:(UIControlEvents)UIControlEventTouchUpInside];
[self.view addSubview:btn];