UIButton not clickable after UITableView scrolled - objective-c

I have a UITableView which is populated with some cells. I have created a UIButton using the following snippet, it is placed next to one of the section headers.
UIButton *addButton = [UIButton buttonWithType:UIButtonTypeCustom];
[addButton addTarget:self action:#selector(addButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[addButton setBackgroundImage:[UIImage imageNamed:#"add.png"] forState:UIControlStateNormal];
addButton.backgroundColor = [UIColor clearColor];
addButton.frame = CGRectMake(270, 150, 29, 29);
The button is placed and works correctly. However, after the view is scrolled (even slightly - like 1 pixel), the button works once and then ceases to respond. When it fails to respond the action for when it is clicked is not triggered and the button doesn't give the 'depressed' shadow. The rest of the application runs as normal and it does not crash.
This seems odd because after I scroll the button is clickable once more before it stops working. The button is used to insert rows into the table, so after it is pressed there is an extra row, possibly this is breaking the bounds or something?
Button pressed function:
- (void)addButtonPressed {
self.addClientTable.editing = YES;
// First figure out how many sections there are
NSInteger lastSectionIndex = [self numberOfSectionsInTableView:self.addClientTable] - 1;
// Then grab the number of rows in the last section
NSInteger lastRowIndex = [self.addClientTable numberOfRowsInSection:lastSectionIndex];
[self.addClientTable insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex]] withRowAnimation:UITableViewRowAnimationRight];
self.addClientTable.editing = NO;
}
Where addClientTable is the UITableView.
What could cause a UIButton to stop responding to clicks and where in my scenario would this be caused by?

I am almost sure that your problem is that your button is out of it superview, and you are not using the clip subviews option in your view that contains the button, or in one of it superviews.
Set to true all the views property clip subviews and see if it appears your button. (We expect that the button disappear)
If you provide more code I can try to help you to solve this problem.
-
Reading again your question, another probable problem to it is that you have one view in front of your button. You can test it changing the background of your view, or something like that.

Related

Custom UIButton background image not appearing until tapped

In app my, if you tap on a certain area a UIPopoverController appears with UIButtons that perform certain tasks when clicked. The UIButtons (called CableDisconnectButton) are a subclassed UIButton so I could add two additional properties to them. I also add UILabels to go over the buttons
However, the background images of the buttons are invisible or don't appear until I tap on the screen somewhere. The UIlabels show up fine, but not the buttons. It can be a tap on the UIPopoverController or anywhere else on the screen. Once I've tapped that first time, the buttons will be there until the app is closed. So, this only happens right after launch and up until I first open that UIPopover. I tap plenty of times before opening the popover.
The functionality of the buttons and everything else works fine, but the background images are hidden on that first launch and I have no idea why.
Here's how I create the buttons and UILabel:
//create custom button
CableDisconnectButton *removeConnectionButton = [CableDisconnectButton buttonWithType:UIButtonTypeCustom];
removeConnectionButton.frame = CGRectMake(x, y, 190, 80);
removeConnectionButton.backgroundColor = [UIColor clearColor];
[removeConnectionButton setBackgroundImage:[UIImage imageNamed:#"images/cable_disconnect_button.png"] forState:UIControlStateNormal];
[removeConnectionButton setBackgroundImage:[UIImage imageNamed:#"images/cable_disconnect_button_over.png"] forState:UIControlStateHighlighted];
//set input and output jacks to button properties
removeConnectionButton.inputJack = inputJack;
removeConnectionButton.outputJack = self.outputJackView;
//add action to button
[removeConnectionButton addTarget:self action:#selector(removeConnectionButtonTarget:) forControlEvents:UIControlEventTouchUpInside];
//create label for output
UILabel *outputConnectionLabel = [[UILabel alloc] initWithFrame:CGRectMake(x+18, y+5, 180, 22)];
outputConnectionLabel.backgroundColor = [UIColor clearColor];
outputConnectionLabel.textColor = [UIColor whiteColor];
outputConnectionLabel.text = self.outputJackView.jackDisplayName;
outputConnectionLabel.font = [UIFont systemFontOfSize:16];
//add subviews
[self addSubview:removeConnectionButton];
[self addSubview:outputConnectionLabel];
I've tried to add a regular, non-custom UIButton and it appears without the tap. I suspect it may have something to do with the subclassed UIButton, but I'm not sure why. The extra properties added to the UIButton are strings that are crucial to the functionality of the and can't be omitted.
After beating my head off the desk for days, I ran into the "Clean Build Folder" option. I've cleaned the project plenty of times, but wasn't aware of "Clean Build Folder". To execute this, simple hold the Option key, click Product from the menu and select Clean Build Folder.
So, if your app isn't behaving the way it should and it makes no sense AT ALL, try this.

Height of UIScrollView get changed?

I am adding UITableView and UIButton in UIScrollView. button is placed below tableview.
Well, when i select any row from table it add a button on that row and every thing is ok till now, but when i click that row second time it remove button added on it but the problem is that along with removing that button it also scroll my table up and button bellow the table reside on its place ie. it leaves gap between table and button.
my table is reloaded every time when a row is clicked.
code for add UIButtonbelow the UITableView
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
mainTable.frame = CGRectMake(mainTable.frame.origin.x, mainTable.frame.origin.y,
mainTable.frame.size.width,
([menuItemsArray count] * 60) + 380);
[scrollView setContentSize:CGSizeMake(320,([menuItemsArray count] * 60) + 80 + 350)];
reserverBtnBottom = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[reserverBtnBottom setFrame:CGRectMake(20.0f,mainTable.frame.size.height,280, 40)];
[reserverBtnBottom addTarget:self action:#selector(reserveBtnAction) forControlEvents:UIControlEventTouchUpInside];
[reserverBtnBottom setBackgroundImage:[UIImage imageNamed:#"normal.png"] forState:UIControlStateNormal];
[reserverBtnBottom setAlpha:1];
[reserverBtnBottom setTitle:#"Reserve this table" forState:UIControlStateNormal];
[reserverBtnBottom setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[scrollView addSubview:reserverBtnBottom];
rest thing goes here
}
What am i missing?
Thanks in advance.
heightForRowAtIndexPath is a bad place for such calculation, as you are changing a single row state this method might be called once to calculate the new height. When it is called the cell still has an old height value, so does the table.
The button position calculation should be moved to layoutSubviews: method of the table and button superview which is a scrollView in your example. The way it should work is that the superview recalculates all the subviews frames once any of them changes it's frame.
Sometimes instead of overriding the layoutSubviews: the frame calculation is handled with the viewController , that's what you were trying to do but you did it in a wrong way. You'll need to find a better place for the frame calculation if you don't want to override scrollView layoutSubviews:.
If you only need the scrollView to add the button below the table, it would be better from my experience to get rid of the scroll view (at least because you do have scroll view in another scroll view which is Never a good practice) and add the button to the table footerView. The footer view is displayed below the table and scrolls together with it.
After long time i resolve my problem. put this code in viewWillAppear instead heightForRowAtIndexPath-
mainTable.frame = CGRectMake(mainTable.frame.origin.x, mainTable.frame.origin.y,
mainTable.frame.size.width,
([menuItemsArray count] * 60) + 380);
[scrollView setContentSize:CGSizeMake(320,([menuItemsArray count] * 60) + 80 + 350)];
and move my reserveBtnBottom to footer of UITableView.
Thanks to A-Live for his great help.

simple animation using an array of images

So this is what I did: I populated the nib with an image view and a round rect button. When the round rect button is pressed, a simple animation is shown using an array of images...code I used to do this looks like this:
imageview.animationImages = images;
and...
[imageview startAnimating];
and then...
[self.view addSubview:imageview];
But the issue is after I added the subview, the superview is though not visible but its still there, so even though the button is not visible it still can be pressed to fire the animation once again. How do I disable this button after the animation is fired. I hope you understood me.Thank you.
I'm assuming you're using an IBAction with a sender parameter. At the end of this method do
UIButton *temp = (UIButton *) sender
temp.enabled = NO;

Adding a button (UIButton) to a custom tableview cell drawn with drawRect:

I am currently working a on project where I have lots of custom table view cells. Part of the requirements is that the cells be able to expand if their default size can not hold all of the content. If they need to be able to expand I have to add a UIButton to the cell and when it is tapped redraw it in a bigger view where all the data fits. Currently in draw rect I essentially do this:
if([self needsExpansion]) {
[self addExpansionButton];
}
-(void)addExpansionButton {
self.accessoryButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.accessoryButton setShowsTouchWhenHighlighted:YES];
UIImage *buttonImage = [UIImage imageNamed:#"blue_arrow_collaps_icon.png"];
[self.accessoryButton setFrame:CGRectMake(280, 82, buttonImage.size.width, buttonImage.size.height)];
[self.accessoryButton setImage:buttonImage forState:UIControlStateNormal];
[self.accessoryButton addTarget:self action:#selector(toggleExpanded) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.accessoryButton];
}
This works fine, except for when I click anywhere else in the cell the button flickers and disappears. Anyone know how to propertly do this?
From the UITableViewCell Class Reference:
You have two ways of extending the
standard UITableViewCell object beyond
the given styles. To create cells with
multiple, variously formatted and
sized strings and images for content,
you can get the cell's content view
(through its contentView property) and
add subviews to it.
Instead of adding the accessory button as a subview of the UITableViewCell, you should add it as a subview of the contentView:
[[self contentView] addSubview:self.accessoryButton];
Have you worked out the following problem in your design approach?: Let's say one of your cells (let's call it A) determines it needs expansion, so you add a button to it. What happens when the user scrolls through the UITableView? For performance reasons, your UITableView delegate should be using dequeueReusableCellWithIdentifier in tableView:cellForRowAtIndexPath:. So you'll be reusing A to display a different row of the table. Do you really want A to have an accessory button? Probably not, since it's now representing a different object.
You're probably better off doing the cell customization at the UITextViewDelegate. In tableView:cellForRowAtIndexPath:, you can determine if the object being displayed at the row specified needs a button, and if it does add it as a subview to the contentView.
Then again, if your table size is always relatively small (say < 50), you can use this approach Jeremy Hunt Schoenherr suggests.

EXC_BAD_ACCESS on button press for button dynamically added to UIView within UIScrollView

OK. It's an iPad app. Within the DetailViewController I have added a UIScrollView through IB and within that UIScrollView I have added a UIView (also added through IB) which holds various dynamically added UITableViews, UILabels and UIButtons.
My problem is that I'm getting errors on the UIButton clicks.
I have defined this method:
- (void)translationSearch:(id)sender {
NSLog(#"in transearch");
[self doSearch];
}
This is how I'm adding the UIButton to the UIView:
UIButton *translationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
translationButton.frame = CGRectMake(6, 200, 200, 20);
translationButton.backgroundColor = [UIColor clearColor];
[translationButton setTitle:#"testing" forState:UIControlStateNormal];
[translationButton addTarget:self action:#selector(translationSearch:) forControlEvents:UIControlEventTouchUpInside];
[verbView addSubview:translationButton];
Now the button is added to the form without any issue but, when I press it, I am getting an EXC_BAD_ACCESS error. I'm sure it's staring me in the face but I've passed my usual time limit for getting a bug like this fixed so any help would be greatly appreciated. The only thing I can think is the fact that the UIButton is within a UIView which is within a UIScrollView which is within the view controller is somehow causing an issue.
Cheers.
Thanks Maz. I have just done that and I have to admit that my assumption about where the error was coming from was wrong. It was a new bit of code, just not the button method call.
Grant me the "dunce" award for this one.