UITableView header view not responding to touches on empty table - ios

I'm having a weird problem, which I'm sure has an easy fix/explanation, but I've spent the weekend trying without luck.
I have a custom UIView as my tableHeaderView, which contains two UIButtons. Pressing one UIButton or the other, changes the data inside the UITableView by changing the dataSource, and doing a [tableView reloadData].
The problem I have is when after pressing one of the buttons, I reload the table but I have no rows (dataSource/table is empty). I can't press the other button to change the dataSource and reload the table back because It becomes unresponsive, doesn't respond to touches.
The only explanation I have is maybe UITableViews don't respond to touches when they are empty? But seems like a bug that the tableHeaderView doesn't respond either..
This happens both in iOS 6 and iOS 7.
PS: I'm aware I could detect the dataSource is empty before doing a reloadData and keep the data for the other dataSource, but I need to show the button as pressed and show a message under it when is empty, so that doesn't help me.
This is how I create the Table header view, and assign it to the tableView.
self.tableCustomHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 48)];
self.tableCustomHeader.backgroundColor = [UIColor whiteColor];
// Configure Header
self.rankingBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.rankingBtn.frame = CGRectMake(3, 4, 157, 40);
self.rankingBtn.adjustsImageWhenHighlighted = NO;
self.rankingBtn.adjustsImageWhenDisabled = NO;
[self.rankingBtn setImage:[UIImage imageNamed:#"amigos_boton_ranking_on.png"] forState:UIControlStateNormal];
[self.rankingBtn setImage:[UIImage imageNamed:#"amigos_boton_ranking_off.png"] forState:UIControlStateDisabled];
[self.rankingBtn setImage:[UIImage imageNamed:#"amigos_boton_ranking_off.png"] forState:UIControlStateHighlighted];
[self.rankingBtn addTarget:self action:#selector(fetchRanking:) forControlEvents:UIControlEventTouchUpInside];
if (self.listType == FriendsListTypeRanking) {
self.alfabeticBtn.enabled = NO;
}
self.alfabeticBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.alfabeticBtn.frame = CGRectMake(160, 4, 157, 40);
self.alfabeticBtn.adjustsImageWhenHighlighted = NO;
self.alfabeticBtn.adjustsImageWhenDisabled = NO;
[self.alfabeticBtn setImage:[UIImage imageNamed:#"amigos_boton_alfabetico_on.png"] forState:UIControlStateNormal];
[self.alfabeticBtn setImage:[UIImage imageNamed:#"amigos_boton_alfabetico_off.png"] forState:UIControlStateDisabled];
[self.alfabeticBtn setImage:[UIImage imageNamed:#"amigos_boton_alfabetico_off.png"] forState:UIControlStateHighlighted];
[self.alfabeticBtn addTarget:self action:#selector(fetchFriends:) forControlEvents:UIControlEventTouchUpInside];
if (self.listType == FriendsListTypeAlfabetic) {
self.alfabeticBtn.enabled = NO;
}
[self.tableCustomHeader addSubview:self.alfabeticBtn];
[self.tableCustomHeader addSubview:self.rankingBtn];
[self.table setTableHeaderView:self.tableCustomHeader];
After that, there is not much else to show. If I return 0 for numberOfRowsInSection, I can no longer press the other UIButton inside the tableHeaderView to change to the other set of data.

Without seeing the implementation of the selectors theres still no way to figure out whats wrong with the app. Though one problem that looks to be easily solved is the fact that you're always setting the alfabeticBtn.enabled to NO.
See:
if (self.listType == FriendsListTypeRanking) {
self.alfabeticBtn.enabled = NO;
}
if (self.listType == FriendsListTypeAlfabetic) {
self.alfabeticBtn.enabled = NO;
}
I would fix that and then if you're still having problems update your question with the selector methods.

Related

ALL UIButton's delay executing block

My project has UIButtons which are taking up to 1 second to execute the block of code.
I have buttons in other projects working fine, but for some odd reason, this project has an annoying delay.
The buttons are dailer numbers, so they need to be pressed quickly:
Heres an example of one:
- (IBAction)phonePressed:(id)sender {
UITapGestureRecognizer *backspaceGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(backspace)];
UIButton *one = [[UIButton alloc] initWithFrame:CGRectMake(menuShadowLayer2.frame.origin.x+10, menuShadowLayer2.frame.origin.y+10, 80, 80)];
one.layer.cornerRadius = 40;
one.layer.borderColor = [UIColor lightGrayColor].CGColor;
one.layer.borderWidth = 1;
[one setBackgroundColor:[UIColor colorWithRed:0/255.0f green:0/255.0f blue:0/255.0f alpha:0.3]];
[one setTitle:#"1" forState:UIControlStateNormal];
[one.titleLabel setTextAlignment:NSTextAlignmentCenter];
[one setTitleColor:[UIColor whiteColor]forState:UIControlStateNormal];
[one.titleLabel setFont:[UIFont fontWithName:#"STHeitiSC-Light" size:50]];
[container addSubview:one];
[one addGestureRecognizer:tap1];
...
- (void)dailed1 {
numberDailed.text = [numberDailed.text stringByAppendingString:#"1"];
NSLog(#"1");
}
Here is another button using UIControlEventTouchUpInside, which is just as slow if not slower.
UIButton *cancel = [[UIButton alloc] initWithFrame:CGRectMake(numberDailed.frame.origin.x, numberDailed.frame.origin.y+200, numberDailed.frame.size.width+40, 110)];
cancel.layer.cornerRadius = 15;
[cancel setImage:[UIImage imageNamed:#"cancel.png"] forState:UIControlStateNormal];
cancel.clipsToBounds = YES;
[container addSubview:cancel];
[cancel addTarget:self
action:#selector(clearNumber:)
forControlEvents:UIControlEventTouchDown];
...
-(IBAction)clearNumber:(id)sender{
[numberDailed setText:#""];
}
I have used a UITapGestureRecognizer as using the Button UIControlEventTouchUpInside or TouchDown was even slower.
When pressing this button (one), I have to wait around half a second to a second before tapping again. This obviously creates frustration when your entering a number and half of the numbers haven't been added to the string.
I have set the UIScrollView to delaysContentTouches = NO;
The button highlights immediately. It simply wont execute the code straight away.
I have used button one as an example, but this applies to ALL UIButtons in my project.
Thoughts?
Where you are using the gesture,
[one addGestureRecognizer:tap1];
instead, you should use the button action
[one addTarget:self action: #selector(dailed1:)];
Couple things. Firstly, create your button like so:
UIButton *numberButton = [UIButton buttonWithType:UIButtonTypeCustom];
numberButton.frame = CGRectMake(...);
Secondly, as others have pointed out, you do not need any gestures, but should attach an action/target to the button:
[numberButton addTarget:self action:#selector(numberDialled:) forControlEvents: UIControlEventTouchUpInside];
Thirdly, create your IBAction:
- (IBAction) numberDialled:(id)sender
The problem turned out to be with the MapBox API(Not Recommended) in my project, removing this sped everything up. All code was fine, have gone back to performing selector and removed the gestures.

Get rid of padding for UITableViewCell custom accessoryView

I have a table view cell with a custom accessoryView, but it seems that the way it's laid out by default creates a 15-point margin on the right side. I want to get rid of it.
I can achieve the desired effect by overriding layoutSubviews, but that breaks edit mode animation (the accessory no longer slides in/out).
Any better way to do this?
Add subview instead of accessoryView
UIButton *deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
deleteBtn.frame = CGRectMake(cell.contentView.frame.size.width-55, 2, 50, 50);
[deleteBtn setBackgroundImage:[UIImage imageNamed:#"trash.png"]
forState:UIControlStateNormal];
deleteBtn.backgroundColor = [UIColor clearColor];
//deleteBtn.alpha = 0.5;
deleteBtn.tag = indexPath.row;
[deleteBtn addTarget:self action:#selector(numberDeleteConfirm:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:deleteBtn];

Subclassing UIView/UIViewController

I need a lot of custom buttons in my app. At the moment I'm using storyboard to define these buttons on every controller that I need. However, I feel that since I need them throughout my app, I'm better off putting in a different view controller/view that subclasses UIView or UIViewController so if I need to make any changes I will just have to do them once as opposed to in different view controllers. What would be the best way to do this? Also can you tell me how can I create buttons programatically? This is what I'm doing at the moment, and I'm getting a completely blank screen.
-(void)viewDidAppear:(BOOL)animated
{
UIButton *testButton = [UIButton buttonWithType:UIButtonTypeCustom];
[testButton setFrame:CGRectMake(0, 390, 100, 40)];
[testButton setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
[setImage:[UIImage imageNamed:#"test_button"] forState:UIControlStateNormal];
[setImage:[UIImage imageNamed:#"test_button"] forState:UIControlStateHighlighted];
[setEnabled:YES];
[self.view addSubview:testButton];
}
there is a chance that your button is way off the visible rect. for adding the button programmatically, you are doing it mostly right. also, images should have the file extension. since you are adding a customButton, if there are no images, then you wont see any button. Try adding a title to your button, which would show up even if there is no image added.
try the code below.
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated]; //you must have a good reason to not add this line.
UIButton *testButton=[UIButton buttonWithType:UIButtonTypeCustom];
[testButton setFrame:CGRectMake(0, 20, 100, 40)];
[testButton setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
[testButton setImage:[UIImage imageNamed:#"test_button.png"] forState:UIControlStateNormal];
[testButton setImage:[UIImage imageNamed:#"test_button.png"] forState:UIControlStateHighlighted];
[testButton setEnabled:YES];
[self.view addSubview:testButton];
}

How to switch views from overlay button?

I've made a button on an overlay which loads every time the camera is accessed. The button responds fine and I've tested it to see whether it was a problem with the selector. I am 100% it's not a problem with the selector(it responded to an NSLog string).
I want to bring up a new view every time it is pressed, but it doesn't do anything even though I've used an assortment of methods. I'm running out of ideas here, I've tried many methods but none work, and I mean none. I made sure I've imported the frameworks right, I've even made new projects and redid everything from step one to make sure it wasn't a problem with the original project.
}
- (UIView*)CommomOverlay {
//Both of the 428 values stretch the overlay bottom to top for overlay function. It
doesn't cover it.
UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,430)];
UIImageView *FrameImg = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,430)];
[FrameImg setImage:[UIImage imageNamed:#"newGraphicOverlay.png"]];
FrameImg.userInteractionEnabled = YES;
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(20, 20, 200, 44); // position in the parent view and set the
size of the button
[myButton setTitle:#"Click Me!" forState:UIControlStateNormal];
// add targets and actions
[myButton addTarget:self action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchUpInside];
[view addSubview:FrameImg];
[view addSubview:myButton];
return view;
}
The below does not work in my -(void)buttonPressed method:
UIViewController *viewControllerName = [[UIViewController alloc] initWithNibName:
(NSString *) bundle:(NSBundle *)];

Using custom UITableViewCell's accessory view to show two items

I've been looking for this for a while, but haven't found an answer (blame poor googling skills). I have a custom UITableViewCell class which, currently, consists of a custom UISwitch and a UILabel. I want to add a button that's only visible (And active) when the switch is set to "Yes". Right now I add the switch to the accessoryView, and leave it. However, the accessory view doesn't really have subviews, as far as I can tell, so here's my question:
Should I just create a UIView that has a button and a switch, size it to fit the cell's accessory view (or will it auto-size itself?), and put that in as the cell's accessory view? And is this typically the way that it's gone about?
Or is there a solution that I'm missing?
Thanks.
Here is an example:
UIButton* btdel = [[UIButton alloc] init];
btdel.tag = indexPath.row;
//[btdel setTitle:#"Delete Event" forState:UIControlStateNormal];
[btdel setBackgroundImage:[UIImage imageNamed:#"ButtonRemove.png"] forState:UIControlStateNormal];
[btdel addTarget:self action:#selector(deleteEvent:) forControlEvents:UIControlEventTouchUpInside];
// bt.titleLabel.frame = CGRectMake(0, 0, 95,24);
btdel.frame = CGRectMake(110, 0, 30,30);
[headerView addSubview:btdel];
[btdel release];
UIButton* bt = [[UIButton alloc] init];
bt.tag = indexPath.row;
[bt setTitle:#"Select a Dress" forState:UIControlStateNormal];
[bt setBackgroundImage:[UIImage imageNamed:#"findDress.png"] forState:UIControlStateNormal];
[bt addTarget:self action:#selector(showDresses:) forControlEvents:UIControlEventTouchUpInside];
bt.font=[UIFont systemFontOfSize:(CGFloat ) 13];
// bt.titleLabel.frame = CGRectMake(0, 0, 95,24);
bt.frame = CGRectMake(0, 3, 95,24);
[headerView addSubview:bt];
cell.accessoryView = headerView;

Resources