programmatically created button click to open a tableview or popup - iphone

I have created a button programmatically in a UITableViewCell and I want it to open a new table view or popup when clicked. Please give me some tutorial or hint. Below is my code:
UIButton *button =[UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(0,0,360,25);
[button addTarget:self action:#selector(dropDownClick) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)dropDownClick
{
//Here I know there should be some code but I am not getting what it should be since I am new to iPad/iPhone development
}

If you just want to show a popup when tapping the button, you can use UIAlertVIew
- (IBAction)dropDownClick {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title of popup"
message:#"Did this popup show?"
delegate:self
cancelButtonTitle:#"Yes"
otherButtonTitles:nil];
[alert addButtonWithTitle:#"No"];
[alert show];
}

Here a sample to do it
//DISEGNO DELLE CELLE
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier;
CellIdentifier = #"CellStorico";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CGRect tRect1 = CGRectMake(0.0f, 3.0f, 768.0f, 40.0f);
id title1 = [[UIButton alloc] initWithFrame:tRect3];
[title1 addTarget:self action:#selector(ClickCheck:) forControlEvents:UIControlEventTouchUpInside];
[title1 setTag:3];
[cell addSubview:title1];
[title1 release];
}
if ([[[Storico objectAtIndex:[indexPath row]] objectForKey:#"Selezionato"] isEqualToString:#"0"]) {
[(UIButton *) [cell viewWithTag:3] setImage:[UIImage imageNamed:#"NoCheck.png"] forState:UIControlStateNormal];
[(UIButton *) [cell viewWithTag:3] setImage:[UIImage imageNamed:#"NoCheck.png"] forState:UIControlStateHighlighted];
[(UIButton *) [cell viewWithTag:3] setImage:[UIImage imageNamed:#"NoCheck.png"] forState:UIControlStateSelected];
} else {
[(UIButton *) [cell viewWithTag:3] setImage:[UIImage imageNamed:#"Check.png"] forState:UIControlStateNormal];
[(UIButton *) [cell viewWithTag:3] setImage:[UIImage imageNamed:#"Check.png"] forState:UIControlStateHighlighted];
[(UIButton *) [cell viewWithTag:3] setImage:[UIImage imageNamed:#"Check.png"] forState:UIControlStateSelected];
}
return cell;
}
Click Management
-(void)ClickCheck:(id)sender{
//Ex. Load a New View
FrmScadenzeGenerali *SchermataScadenzeGenerali=[[FrmScadenzeGenerali alloc] initWithNibName:#"FrmScadenzeGenerali" bundle:nil];
[[self navigationController] pushViewController:SchermataScadenzeGenerali animated:YES];
[SchermataScadenzeGenerali release];
//Ex. PopUp a View
[self.view insertSubview:[TabTestata view] atIndex:0];
//Show a Message
UIAlertView *Alert = [[UIAlertView alloc] initWithTitle:#"Attenzione!" message:#"Error Text Message To Show!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[Alert show];
[Alert release];
}

I assume you are using a UINavigationController with your UITableView.
If so, you can do try this to make it open a new table view:
Make a new class which is a subclass of UITableViewController. Make sure the checkbox named "With XIB for user interface" is checked. Give it a name, i.e. "MyTableViewController".
Open the implementation file (the one ending in .m) of your class where you have your dropDownClick method, and import your new class with #import "MyTableViewController.h". Do this at the top of your class (.m file).
Edit your dropDownClick method to the following lines:
-(IBAction)dropDownClick
{
MyTableViewController *vc = [[MyTableViewController alloc] initWithNibName:#"MyTableViewController"]; // Loads a .xib file called "MyTableViewController.xib"
[self.navigationController pushViewController:vc animated:YES]; // This is where the swapping happens.
[vc release]; // Remember to do this if your app does not use ARC.
}
You could also do this without using a .xib, but then it would be a bit different.

Related

Adding buttons to viewForFooterSection UITableView

after some discussion on this topic I'm attemting to implement 2 buttons on the footerview on a UItableView. To create the buttons, I declare them on the declaration .h file, synthesized on the implementation .m file and then, I created them by code, like this:
- (UIButton *)resetButton{
if (resetButton == nil)
{
resetButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
resetButton.frame = CGRectMake(20.0, 40 , 95.0, 37.0);
[resetButton setTitle:#"Reset" forState:UIControlStateNormal];
resetButton.backgroundColor = [UIColor clearColor];
[resetButton addTarget:self action:#selector(resetAction:) forControlEvents:UIControlEventTouchDown];
resetButton.tag = 1;
}
return resetButton;
}
and then, I implemented this code into the UITableView delegate method:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView* customView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)];
[customView addSubview:self.resetButton];
[customView addSubview:self.calculateButton];
return [customView autorelease];
}
by doing so, the buttons appear on the screen however, when I tap them, nothing happens (I implemented a AlertView on the actions to check if they work.
any help here?
Thanks!
EDIT: the actions linked to the button:
-(IBAction)resetAction:(id)sender {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Reset"
message:#"You just pressed the Reset button"
delegate:self
cancelButtonTitle:#"Acknowledged"
otherButtonTitles:nil];
[alert show];
[alert release];
}
I think what you are missing is - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section.
Without this the custom footer will be height 0. The reason you can still see the button is because clipsToBounds is NO by default for the custom view.

how to create custom button on table view cell

I want to create custom button in table view.in that by clicking on that button the label will be create with current date.In that button i also have to implement checkbox functionality. I have implemented following code for checkbox functionality:It works fine but i can i create label by checking them YES.Thanks in advance.
UIButton *btnUncheck=[[UIButton alloc] initWithFrame:CGRectMake(260, 35, 20, 20)];
//btnUncheck=[UIButton buttonWithType:UIButtonTypeCustom];
btnUncheck.tag=indexPath.row;
[btnUncheck setImage:[UIImage imageNamed:#"NO.png"] forState:UIControlStateNormal];
[btnUncheck addTarget:self action:#selector(checkBoxClicked:) forControlEvents:UIControlEventTouchUpInside];
[btnUncheck release];
[cell.contentView addSubview:view];
return cell;
}
-(IBAction)checkBoxClicked:(id)sender
{
if(favoriteChecked==NO)
{
[sender setImage:[UIImage imageNamed:#"YES.png"] forState:UIControlStateNormal];
favoriteChecked=YES;
[lblAchievementreward setHidden:NO];
}
else
{
[sender setImage:[UIImage imageNamed:#"NO.png"] forState:UIControlStateNormal];
favoriteChecked=NO;
}
Yes, you can. In checkBoxClicked:, save the row of the checked item in an instance variable. Then, reload the row so that cellForRowAtIndexPath is called again. Something like-
self.checkedRow = sender.tag;
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathWithIndex:sender.tag]] withRowAnimation:UITableViewRowAnimationNone];
Then, in cellForRowAtIndexPath:, check for self.checkedRow and add a label. Something like-
if(indexPath.row == self.checkedRow)
{
UILabel* label = [[UILabel alloc] init];
//label.text = [NSDate date]; //use date formatters here
[cell.contentView addSubview:label];
}

How to customize Buttons in UIActionSheet?

I want to change the image of the buttons of UIActionSheet, I have images for each button, and I want each button show the image I want. I searched the web I found a lot of answers but they didn't work.
Here is the initialization of the UIActionSheet
-(IBAction)showActionSheet:(id)sender {
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:#"title" delegate:self cancelButtonTitle:#"Cancel Button" destructiveButtonTitle:nil otherButtonTitles:#"Other Button 1", #"Other Button 2", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleDefault;
[popupQuery showInView:self.view];
[popupQuery release];
}
I create a subclass CustomActionSheet derived UIActionSheet, and implement a method called customizeGUI.
I use CustomActionSheet like UIActionSheet, except I must call method customizeGUI of subclass in willPresentActionSheet delegate:
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
if ([actionSheet isKindOfClass:[CustomActionSheet class]]) {
CustomActionSheet *sheet = (CustomActionSheet*)actionSheet;
[sheet customizeGUI];
}
}
(CustomActionSheet.m)
- (void)customizeGUI {
UIImageView *imgvwBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bg_actionsheet.png"]];
CGRect rect = self.bounds;
imgvwBackground.frame = rect;
[self insertSubview:imgvwBackground atIndex:0];
[imgvwBackground release];
int buttonIndex = 0;
UIImage *imgButtonDestructive = [UIImage imageNamed:#"btn_actionsheet_destructive.png"];
UIImage *imgButtonCancel = [UIImage imageNamed:#"btn_actionsheet_cancel.png"];
UIImage *imgButtonNormal = [UIImage imageNamed:#"btn_actionsheet_normal.png"];
for (UIView *sub in self.subviews) {
NSString *className = [NSString stringWithFormat:#"%#", [sub class]];
if ( ([className isEqualToString:#"UIThreePartButton"]) //iOS 4
|| ([className isEqualToString:#"UIAlertButton"]) ) { //iOS 5
rect = sub.frame;
sub.hidden = YES;
UIButton *btn = [[UIButton alloc] initWithFrame:rect];
UIImage *imgForButton = nil;
if (buttonIndex == self.cancelButtonIndex) {
imgForButton = imgButtonCancel;
}
else if (buttonIndex == self.destructiveButtonIndex) {
imgForButton = imgButtonDestructive;
}
else {
imgForButton = imgButtonNormal;
}
NSString *sTitle = [self buttonTitleAtIndex:buttonIndex];
btn.titleLabel.font = [UIFont boldSystemFontOfSize:19];
[btn setBackgroundImage:imgForButton forState:UIControlStateNormal];
[btn setTitle:sTitle forState:UIControlStateNormal];
btn.tag = buttonIndex;
[btn addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
[btn release];
buttonIndex++;
}
}
}
- (void)buttonClicked:(id)sender {
UIButton *btn = sender;
if ([self.delegate respondsToSelector:#selector(actionSheet:clickedButtonAtIndex:)]) {
[self.delegate actionSheet:self clickedButtonAtIndex:btn.tag];
}
[self dismissWithClickedButtonIndex:btn.tag animated:YES];
}
Hope this way can help you and give you an idea to customize UIActionSheet
If you change these sizes, not only might you make your application less usable, but that may violate Apple's Human Interface Guidelines, leading to a rejection of your application when submitted.
Here is the example how to use UiActionsheet by Apple
Looks like you'll just have to create your own class. I'd look into subclassing either UIView or UIActionSheet. There are those PSD things around that you can get the images you'll need, pending copyright.
EDIT: If you do end up creating your own class, and its any good, consider uploading it to http://cocoacontrols.com/

message sent to deallocated instance issue

I have been debugging the following issue for the past couple hours and can't seem to come up with a good conclusion.
-[NSIndexPath row]: message sent to deallocated instance 0x506cf90
I am implementing a swipe recognizer on each cell on the UITableView. Whenever a swipe is detected, the code below will be called. What it does is to show/hide a subview in the cell. If the subview already shows then it hides, otherwise it shows. If a subview is already shown on cell 5 and a swipe is detected on cell 3 then we remove that subview first then add the subview on cell 3.
I tried the code below and it seems to works with some cells. However, there is a cell particularly at the bottom of the UITableView in which if I try to hide the subview it gives me the error above. It works just perfectly fine for the other cell, just cells at the bottom. Why is this?
The code is as follows:
- (void)swipe:(UISwipeGestureRecognizer *)recognizer direction:(UISwipeGestureRecognizerDirection)direction
{
if (recognizer && recognizer.state == UIGestureRecognizerStateEnded)
{
// Get the table view cell where the swipe occured
CGPoint location = [recognizer locationInView:self.table];
NSIndexPath* indexPath = [self.table indexPathForRowAtPoint:location];
ConvoreCell* cell = (ConvoreCell *) [self.table cellForRowAtIndexPath:indexPath];
[self.table beginUpdates];
NSLog(#"ROW is %d", global.row);
//removing the options view at the other cell before adding a new one
if (global != nil && global.row != indexPath.row){
[sideSwipeView removeFromSuperview];
[sideSwipeView release];
sideSwipeView = nil;
}
//options already exist, we need to remove it
if (sideSwipeView != nil){
[sideSwipeView removeFromSuperview];
[sideSwipeView release];
sideSwipeView = nil;
slide = NO;
} else {
//options do not exist and therefore we need to add it
NSArray * buttonData = [[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:#"Mark Read", #"title", #"mark.png", #"image", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Track", #"title", #"play.png", #"image", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Leave", #"title", #"delete.png", #"image", nil],
nil] retain];
NSMutableArray * buttons = [[NSMutableArray alloc] initWithCapacity:buttonData.count];
sideSwipeView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.frame.size.height-25, 320, 25)];
[sideSwipeView setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin];
[sideSwipeView setBackgroundColor:[UIColor colorWithPatternImage: [UIImage imageNamed:#"dotted-pattern.png"]]];
[sideSwipeView setTag:-10];
CGFloat leftEdge = BUTTON_LEFT_MARGIN;
for (NSDictionary* buttonInfo in buttonData)
{
if (!([[buttonInfo objectForKey:#"title"] isEqualToString:#"Mark Read"] && [[[groups objectAtIndex:indexPath.row] unread] intValue] == 0))
{
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
UIImage* buttonImage = [UIImage imageNamed:[buttonInfo objectForKey:#"image"]];
if ([[[groups objectAtIndex:indexPath.row] tracked] intValue] == 1 && [[buttonInfo objectForKey:#"title"] isEqualToString:#"Track"]){
buttonImage = [UIImage imageNamed:#"pause.png"];
[button setSelected:YES];
} else
[button setSelected:NO];
button.frame = CGRectMake(leftEdge, 0, buttonImage.size.width, buttonImage.size.height);
UIImage* grayImage = [self imageFilledWith:[UIColor colorWithWhite:0.9 alpha:1.0] using:buttonImage];
[button setImage:grayImage forState:UIControlStateNormal];
if ([[buttonInfo objectForKey:#"title"] isEqualToString:#"Mark Read"]){
[button addTarget:self action:#selector(markRead:) forControlEvents:UIControlEventTouchUpInside];
} else if ([[buttonInfo objectForKey:#"title"] isEqualToString:#"Track"]){
[button addTarget:self action:#selector(track:) forControlEvents:UIControlEventTouchUpInside];
} else if ([[buttonInfo objectForKey:#"title"] isEqualToString:#"Leave"]){
[button addTarget:self action:#selector(leave:) forControlEvents:UIControlEventTouchUpInside];
}
[button setTag:indexPath.row];
[buttons addObject:button];
[sideSwipeView addSubview:button];
leftEdge = leftEdge + buttonImage.size.width + BUTTON_SPACING;
}
}
[cell.contentView addSubview:sideSwipeView];
[buttons release];
[buttonData release];
global = indexPath;
slide = YES;
}
[self.table endUpdates];
[self.table deselectRowAtIndexPath:indexPath animated:YES];
}
}
Now the issue here is that the pointer to indexPath somehow got deallocated. I was able to get around this by making a copy of the indexPath instead of just having a reference to the pointer. So I did:
global = [indexPath copy];
for some reason after this method is called it deallocates indexPath and I am not sure who does it.. I think iOS does it... is it true?
NSIndexPath* indexPath = [self.table indexPathForRowAtPoint:location];
That returns an autoreleased instance. So, yes, your assignment to global needs to retain the object. copy effectively returns a retained instance.
Don't leak, though. If you just do:
global = [indexPath copy];
And you don't release the original value of global first, you'll leak.
Oh, and: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

can i display alert view with the table view with segmented controls in every cell

i want to display the table view in alert view. This table view contains segmented control.
these segmented controls are for on/off the audio, image, text. so there will be 3 cells with segmented controls.
how to do this
please help me out
Thank u
Adding UISegmentedControls (or UISwitches, which I would personally recommend for a simple on/off option) is easy enough to put in table view cells using the accessoryView property.
Your view controller (or whatever object you're using to control this thing) must implement the UITableViewDataSource protocol.
#interface MyViewController : UIViewController<UITableViewDataSource, UITableViewDelegate> {}
#end
Add the controls in tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* const SwitchCellID = #"SwitchCell";
UITableViewCell* aCell = [tableView dequeueReusableCellWithIdentifier:SwitchCellID];
if( aCell == nil ) {
aCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SwitchCellID] autorelease];
aCell.textLabel.text = [NSString stringWithFormat:#"Option %d", [indexPath row] + 1];
aCell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
aCell.accessoryView = switchView;
[switchView setOn:YES animated:NO];
[switchView addTarget:self action:#selector(soundSwitched:) forControlEvents:UIControlEventValueChanged];
[switchView release];
}
return aCell;
}
Or, if you're set on segmented controls, replace the UISwitch stuff above with something like:
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"On", #"Off", nil]];
segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
segmentedControl.segmentedControlStyle = UISegmentedControlStylePlain;
segmentedControl.frame = CGRectMake(75, 5, 130, 30);
segmentedControl.selectedSegmentIndex = 0;
[segmentedControl addTarget:self action:#selector(controlSwitched:) forControlEvents:UIControlEventValueChanged];
aCell.accessoryView = segmentedControl;
[segmentedControl release];
I would personally put these options in a regular view (probably accessible from an options button which does the flip transition, like many iPhone apps do). I don't think putting it in an alert view is a very good user experience.
However, I have written a few blog posts showing how to put various views into alert views (text field, which is kinda useful, and web view, which is arguably not).
So, if you're really dead set on putting this in an alert view, you can totally do that, like this:
- (void) doAlertWithListView {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Preferences"
message:#"\n\n\n\n\n\n\n"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
UITableView *myView = [[[UITableView alloc] initWithFrame:CGRectMake(10, 40, 264, 150)
style:UITableViewStyleGrouped] autorelease];
myView.delegate = self;
myView.dataSource = self;
myView.backgroundColor = [UIColor clearColor];
[alert addSubview:myView];
[alert show];
[alert release];
}
It will look something like this:
The answer above works great, but on the iPad the line myView.backgroundColor = [UIColor clearColor];
doesn't seem to remove the grey rectangular area around the table. I find that the following does the job: tableView.backgroundView.alpha = 0.0;