I have a UITableViewController, when there is no data to populate the UITableView, I want to add a button, which uses an image. So, rather than the user seeing a tableview with no records, they will see an image that says, "No records have been added, Tap to add one", then they click and we create a new one.
I assumed I would just hide the UITableView, then create the button, but I never see the button. Here I am using:
if ([[fetchedResultsController sections] count] == 0) {
self.tableView.hidden = YES;
// Create button w/ image
UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 100, 50);
[btn setImage:[UIImage imageNamed:#"no-rides.png"] forState:UIControlStateNormal];
[self.view addSubview:btn];
}
Ideas on why I would never see the button? When I show this view, it seems to have a transparent background for a second, then changes white...
I am not sure if it works but you can try this:
If your view controller is not a UITableViewController and it contains a UITableView
[self.tableView removeFromSuperview]; then [self.view addSubview];
If your view controller is a UITableViewController, you may need to consider to set the first row to contain the image and text. Then, you can handle the event: tableView:didSelectRowAtIndexPath: and if user click on the first cell, you trigger the method handle the button event
In a UITableViewController, self.view could be self.tableView in which case hiding the table would also hide the button. Try using a custom UIViewController and creating either the table or the button as a subview of self.view instead.
Alternately, when there is no data, you can create a single custom cell containing your button and use that instead of normal cells.
I believe you can add the button to the table footer, as the table footer is shown even when there are no cells. (Note, this is different to a section footer.)
By default the tableFooterView property of the UITableView is nil. So just create your button, and then do:
self.tableView.tableFooterview = btn;
For all future travelers, I simply set .userInteraction = true (Swift) and it worked like a charm. All in all:
tableView.backgroundView = constructMyViewWithButtons()
tableView.backgroundView!.userInteraction = true
Related
I have a custom table view cell view that contains a button. I initialize the button to setBackgroundImage to an empty circle in its normal state. I also setImage to a checkmark image for its selected state.
checkmarkButton = [[UIButton alloc] initWithFrame:CGRectMake(kLeftMargin, kTopMargin, kButtonSize, kButtonSize)];
[checkmarkButton setBackgroundImage:[UIImage imageNamed:#"empty-circle.png"] forState:UIControlStateNormal];
[checkmarkButton setImage:[UIImage imageNamed:#"checkmark.png"] forState:UIControlStateSelected];
[checkmarkButton addTarget:self action:#selector(checkmarkButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:checkmarkButton];
When the button is clicked on, I set the button as selected and told to redraw so that the button looks like a circle with a checkmark in it. Click on it again and selected is set to NO and the cell is told to redraw so that it's an empty circle.
- (void)checkmarkButtonPressed:(id)sender
{
[checkmarkButton setSelected:!checkmarkButton.selected];
[managedObjectContext save:nil];
}
My problem is that this button exists in a custom table view cell view, which seems to control how it's drawn in a way that I can't identify. When I long-click (touch down in the cell and staying in the cell without touching up for a while) on a cell whose button is set selected (should display a checkmark in a circle), the checkmark disappears until I touch up. When I touch up, the state of the cell is correct. It's just wrong while I am long-clicking the cell.
So, how do I control how that button is drawn when I long-click on the cell?
I'm not sure if this is exactly your case because I didn't see your sources. But please check the Highlighted state of your button. When UIButton is placed on UITableViewCell then table controls your UIButton: on cell touch down (long touch) UIButton as well as UITableViewCell change its state to Highlighted and returns to Default or Selected state on touch up.
UPDATE:
I agree it is unexpected behavior. You can create subclass of UIButton and reimplement this call to leave it empty to prevent calling super method:
- (void)setHighlighted:(BOOL)highlighted;
Example:
#interface XButton : UIButton
#end
#implementation XButton
- (void)setHighlighted:(BOOL)highlighted { }
#end
This should prevent state changing by table.
when you click and hold a button the state that is getting called is the highlighted state, thus when you release the click the state returns to UIControlStateNormal
There are three sections in my UIView in the iOS application. May I know how can I only change to another view within one of the sections only?
For example:
When I press the next page button, section 2 will change to another UIView. However sections 1 and sections 3 will still remain.
Any help?
Thank you so much!
on Next Page button click function just do this
[pageSectionTwo removeFromSuperview];
[self addSubview:pageSectionTwoNewView];
"pageSectionTwo" this is the view which should be replaced to get another View in place
"pageSectionTwoNewView" this is the View which will show after you initial View in section 2 replaces
Add another UIButton, set its frame the same as UIButton in section 2, and hide it
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn2.frame = btn1.frame;
btn2.hidden = YES;
[self.view addSubView:btn2]; // This will add btn2 to you view
When you are ready to change your UIButtons, do the following
btn1.hidden = YES;
btn2.hidden = NO;
That will hide the first one and show the second.
In my iPhone app, I am using a tableView and have added the imageView as ContentView in my tableViewcell.
At the click of button I am changing the tableView Contents. So every time I click a button it should show the corresponding image in tableViewCell.
Problem:
Suppose I am loading images 1.png, 2.png and 3.png in tableView on click of button A, B and C respectively.
Now let us consider that initially I clicked button A and 1.png appears. Now when I click the button B then 2.png appears but 1.png also remains in background. So basically it overlaps the tableViewCell with a new image.
Troubleshooting I already have done:
1) I tried releasing imageView and setting imageView.image = nil;
2) I tried reloading the table and empty out table before each button click.
3) Even I tried putting the whole code in if(cell==nil) clause of cellForRowAtIndexPath method
Have you tried clearing the cell's contentView?
for(UIView* subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
If you use three different imageViews then try to imgView1.hidden=FALSE;imgView.hidden=TRUE;imgView3.hidden=TRUE on button1 click event.
same way for buttton2 and button3.
It seems that you have set the image in the (cell==nil) block. If yes please comment that out.
Do it like:
if(cell ==nil){
//add image view here.
}
UIImageView *imgView = (UIImageView *)[cell.contentView viewWithTag:ImgViewTag];
if(condition)
imgView.image = someImage;
else
imgView.image = nil;
I have got the answer and I am really thankful to Ben Gottlieb:
remove image from tableViewCell created programmatically
In my app, I have a table view that has about eight cells. There is a navigation bar at the top. When a user touches a cell, nothing happens for about 1/2 second. Then the touched cell highlights blue and immediately the new view slides into position.
The problem is that there is no feedback to the user about which cell he touched until just before the new view slides into position.
For example, when I explore the tables in the iPhone's Settings application, when you touch a cell, the cell immediately turns blue, and then there is a 1/2 second delay, and then you see the new view.
How do I get my table's feedback of highlighting the cells to happen immediately? I am using tableView didSelectRowAtIndexPath:, and each cell has an accessory button.
Thanks for any insight.
are you using a custom-drawn cell (with a drawRect override) or something like that?
if you have a custom drawRect method, you'll need to do something like this (based off the code for tweetie, found here):
//default colors for cell
UIColor *backgroundColor = [UIColor whiteColor];
UIColor *textColor = [UIColor blackColor];
//on highlight, swap colors
if(self.highlighted){
backgroundColor = [UIColor clearColor];
textColor = [UIColor whiteColor];
}
that should give you the default behavior.
It sounds like the screen is refreshing after the new slide has been processed. You need to refresh the screen before rendering the new slide view.
a few things:
it's probably best to have a property in beforeViewController so it can set its own title on load (instead of setting it from the parent class).
second, why are you setting the back button for the current class? youre also leaking that (you alloc the UIBarButtonItem but dont release it).
NewViewController *newViewController = [[[NewViewController alloc]
initWithNibName:#"New" bundle:nil] autorelease];
newViewController.name = [self.listData objectAtIndex:indexPath.row];
[self.navigationController pushViewController:beforeAfterViewController animated:YES];
then in NewViewController, you have
- (void) viewDidLoad{
self.title = self.name;
}
re: your secondary question: if you pop the child controller using [self.navigationController popViewControllerAnimated:YES], the parent view should auto-deselect the row that was previously selected. it shoulnt stay selected unless you are forcing it to stay that way.
you don't need to do anything like [self.tableView deselectRowAtIndexPath:] unless you are not pushing child views (and doing something like checkmarking a cell that the user tapped).
You may put these 2 lines of code at the beginning of the didSelectRowAtIndexPath method:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:YES animated:YES];
it should first highlight the cell before processing other program logic.
Is it possible to set up a UITextField with a leftView so that if a user clicks into the UITextField the keyboard shows but if they click on an icon in the leftView another method is called (i.e., one that displays a UIPickerview)?
Have you checked that the leftFieldViewMode is set to something other than never
[textField setLeftViewMode:UITextFieldViewModeAlways];
Instantiate a button as u do normaly
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(0,0,30,30)];
[btn setTitle:#"title" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(BtnClick) forControlEvents:UIControlEventTouchUpInside];
Instantiate a textfield as you do normally
UITextField *txtfield1=[[UITextField alloc]initWithFrame:CGRectMake(10, 10,300,30)];
[txtfield1 setBackgroundColor:[UIColor grayColor]];
[txtfield1 setPlaceholder:#" Enter"];
To set a view in left side(there is right view also available)
[txtfield1 setLeftView:btn];
if u want the view to show always then below code does it
[txtfield1 setLeftViewMode:UITextFieldViewModeAlways];
if u want the view to show never then
[txtfield1 setLeftViewMode:UITextFieldViewModeNever];
if u want the view to show if the textfield is not edited then below
[txtfield1 setLeftViewMode:UITextFieldViewModeUnlessEditing];
if u want the view to show if the textfield is edited then
[txtfield1 setLeftViewMode:UITextFieldViewModeWhileEditing];
button click event and pop over
-(void)BtnClick
{
//Usual pop over coding goes here
}
Have you tried using a UIButton for this task? From the documentation for the leftView property:
If your overlay view does not overlap
any other sibling views, it receives
touch events like any other view. If
you specify a control for your view,
the control tracks and sends actions
as usual. If an overlay view overlaps
the clear button, however, the clear
button always takes precedence in
receiving events.
So create a UIButton instance, configure its appearance and actions as needed, then set it as the leftView property.