See the following code, it is simply a method, and I am unable to understand the memory management issues in it, let me know, what is happening in the following code, and why?
-(IBAction)selectMarina {
NSLog(#"Select Marina");
actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
[actionSheet addSubview:pickerView];
//[pickerView release];
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Close"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:#selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
//[closeButton release];
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
[pickerView selectRow:0 inComponent:0 animated:NO];
}
here it is saying Potential leak of object allocated on line 112 and stored into close button
it is showing such msg on line
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
How can I do proper memory management in this code, and can you specify it in details
Thanks
First of all you need to release both the instance pickerView and closeButton.
As per rule whenever u alloc an object it has to be released once it job is completed. In your case after adding both the instance to the subview are not required so they has to released. Otherwise it will show the leak as you mentioned.
For more understanding refer memory guide or for a quick look click http://www.raywenderlich.com/2657/memory-management-in-objective-c-tutorial
Related
I have a textfield. once I tap on that I want a UIPickerView to pop out and select an item from the UIPickerView and after once I am done with the selection I want to confirm the selection by tapping on an UIActionSheet which has confirm button on it.So my requirement is to have a UIActionSheet and beneath that a picker view. I am just a beginner in iOS development and I am still not familiar with the technical terminologies. So please bear with my informal way of asking questions.
Here is my block of code:
creating UIPickerView and UIActionSheet
UIActionSheet *confirmRoomSelectionAS =[[UIActionSheet alloc]initWithTitle:#"" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Done",nil];
UIPickerView *roomTypePicker=[[UIPickerView alloc]init];
[confirmRoomSelectionAS addSubview:roomTypePicker];
[confirmRoomSelectionAS showInView:self.view];
[confirmRoomSelectionAS setBounds:CGRectMake(0, 0, 320, 600)];
[roomTypePicker setFrame:CGRectMake(0, 170, 320, 216)];
[roomTypePicker setDataSource:self];
[roomTypePicker setDelegate: self];
roomTypePicker.showsSelectionIndicator = YES;
Try like this,
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
[actionSheet showInView:[self.view window]];
[actionSheet setBounds:CGRectMake(0, 0, 320, 390)];
[actionSheet addSubview:[self createToolbar:#"Test"]];
UIPickerView *picker = [[UIPickerView alloc] init];
picker.frame = CGRectMake(0, 44, 320, 162);
picker.showsSelectionIndicator = YES;
picker.dataSource = self;
picker.delegate = self;
[actionSheet addSubview:picker];
- (UIView *)createToolbar:(NSString *)titleString {
UIToolbar *inputAccessoryView = [[UIToolbar alloc] init];
inputAccessoryView.barStyle = UIBarStyleBlackOpaque;
inputAccessoryView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[inputAccessoryView sizeToFit];
CGRect frame = inputAccessoryView.frame;
frame.size.height = 44.0f;
inputAccessoryView.frame = frame;
UIBarButtonItem *doneBtn =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)];
UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *cancelBtn =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancel:)];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0 , 11.0f, 100, 21.0f)];
[titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setTextColor:[UIColor whiteColor]];
[titleLabel setText:titleString];
[titleLabel setTextAlignment:UITextAlignmentCenter];
UIBarButtonItem *title = [[UIBarButtonItem alloc] initWithCustomView:titleLabel];
NSMutableArray *array = [NSMutableArray arrayWithObjects:cancelBtn,flexibleSpaceLeft,title,flexibleSpaceLeft, doneBtn, nil];
[inputAccessoryView setItems:array];
[doneBtn release];
[title release];
[titleLabel release];
[flexibleSpaceLeft release];
[cancelBtn release];
return [inputAccessoryView autorelease];
}
- (void)done:(id)sender {
}
- (void)cancel:(id)sender {
}
It will be like,
3 things I thought you should modify:
1) add your cancel button manually, to later better check the cancel button pressing event
UIActionSheet * confirmRoomSelectionAS = [[UIActionSheet alloc]
initWithTitle:#""
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[confirmRoomSelectionAS addButtonWithTitle:#"Done"];
confirmRoomSelectionAS.cancelButtonIndex = [confirmRoomSelectionAS addButtonWithTitle: #"Cancel"];
[confirmRoomSelectionAS showInView:self.view];
2) implement your actionsheet delegate method
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == actionSheet.cancelButtonIndex) {
// cancel button pressed;
return;
}
}
3) You should declare *UIPickerView picker in your .h to later check of its selected value in the previous delegate method (also including the Done check) by adding sthing like this:
NSInteger row;
row = [picker selectedRowInComponent:0];
I want to
show a picker view (sliding up)
deactivate the background while it's visible
show (UIActionSheet) buttons at the bottom (not at the top)
It seems to me an easy solution at first since you can find code for adding a picker view to an action sheet everywhere in the web but all solutions position the buttons at top and I need to put the buttons at the bottom of the action sheet (alignment?).
Is this possible? I guess it is if I look at: Example
Regards
Jeven
EDITED (my solution based on coded dads solution)
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 0, 0, 0);
UIPickerView *pickerView = [[UIPickerView alloc]initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
UISegmentedControl *backButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Back", nil]] ;
[backButton addTarget:self action:#selector(someFunction:) forControlEvents:UIControlEventValueChanged];
backButton.tintColor = [UIColor colorWithRed:0.10 green:0.20 blue:0.52 alpha:0.5];
backButton.segmentedControlStyle = UISegmentedControlStyleBar;
[backButton addTarget:self action:#selector(btnActionCancelClicked:) forControlEvents:UIControlEventAllEvents];
backButton.frame = CGRectMake(20.0, 220.0, 280.0, 40.0);
UISegmentedControl *acceptButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Accept", nil]] ;
[acceptButton addTarget:self action:#selector(anotherFunction:) forControlEvents:UIControlEventValueChanged];
acceptButton.tintColor = [UIColor colorWithRed:0.10 green:0.20 blue:0.52 alpha:0.5];
acceptButton.segmentedControlStyle = UISegmentedControlStyleBar;
acceptButton.frame = CGRectMake(20.0, 280.0, 280.0, 40.0);
[actionSheet addSubview:pickerView];
[actionSheet addSubview:backButton];
[actionSheet addSubview:acceptButton];
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
[actionSheet setFrame:CGRectMake(0,150,320, 400)];
... then just apply iPhone 5/iphone 4 dependent view size constraints
EDITED 2:
Just another hint! Originally I wanted to use the standard Actionsheet, but didn't want to place the pickerview at the bottom. I didn't find a way how to move the buttons. Obviously it s really simple: Add UIView as subView on UIActionSheet Good to know ;)
You have 2 possibilites:
Option1: the big tweak.
ActionSheet shows the buttons with the order defined during init. So place some dummy buttons at the top and Cancel will be the only visible, all other buttons will be hidden by the pickerview. Code (warning-tweak at otherButtonTitles):
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:#"Actionsheet"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"1", #"2", #"3", #"4", nil];
UIPickerView *pickerView = [[UIPickerView alloc] init];
pickerView.delegate = self;
pickerView.dataSource = self;
[menu addSubview:pickerView];
[menu showInView:self.view];
[menu setBounds:CGRectMake(0,0,320, 500)];
CGRect pickerRect = pickerView.bounds;
pickerRect.origin.y = 35;
pickerView.frame = pickerRect;
Option2: the selfmade
menu = [[UIActionSheet alloc] initWithTitle:#"Actionsheet"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
UIPickerView *pickerView = [[UIPickerView alloc] init];
pickerView.delegate = self;
pickerView.dataSource = self;
CGRect pickerRect = pickerView.bounds;
pickerRect.origin.y = 35;
pickerView.frame = pickerRect;
UIButton *startbtn = [UIButton buttonWithType:UIButtonTypeCustom];
startbtn.frame = CGRectMake(80,230, 170, 73);
[startbtn setBackgroundImage:[UIImage imageNamed:#"yourbutton.png"] forState:UIControlStateNormal];
[startbtn addTarget:self action:#selector(pressedbuttonCancel:) forControlEvents:UIControlEventTouchUpInside];
[menu addSubview:pickerView];
[menu addSubview:startbtn];
[menu showInView:self.view];
[menu setFrame:CGRectMake(0,150,320, 350)];
Check that for option2 the button should be on the actionsheet unless the clicks will not be dispatched to the selector method.
HEllo,
can any one guide me for the following
I want to add an ActionSheet with customize image.
In ActionSheet I want to place a table view for the data.
Two buttons(cancel & done)
Thanks....
check my answer. I am using this code to display UITableView in actionsheet.
In .h file
#property (strong, nonatomic) IBOutlet UITableView *tableView;
In .m file
-(void)addTableViewInActionSheet
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 50, 320, 210)];
_tableView.dataSource = self;
_tableView.delegate = self;
[actionSheet addSubview:_tableView];
UISegmentedControl *doneButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Done"]];
doneButton.momentary = YES;
doneButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
doneButton.segmentedControlStyle = UISegmentedControlStyleBar;
doneButton.tintColor = DEFAULT_COLOR;
[doneButton addTarget:self action:#selector(doneBtnClicked:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:doneButton];
UISegmentedControl *cancelButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Cancel"]];
cancelButton.momentary = YES;
cancelButton.frame = CGRectMake(10, 7.0f, 60.0f, 30.0f);
cancelButton.segmentedControlStyle = UISegmentedControlStyleBar;
cancelButton.tintColor = [UIColor blackColor];
[cancelButton addTarget:self action:#selector(cancelBtnClicked:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:cancelButton];
[actionSheet showInView:self.view];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
You don't need to added table in UIActionSheet just add 7 - 8 buttons in UIActionSheet and it will automatically be placed as table.
See the attached screenshot..
I've created a UIPickerView, which displays on button click. The question is how I fill in the rowItems
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select Location"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,100,0,0)];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
[actionSheet addSubview:pickerView];
[pickerView release];
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:NSLocalizedString(#"Done", #"")]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:#selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
[closeButton release];
[actionSheet showInView:self.view];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
and How do I get value when "done" is clicked.
you've set the delegate of the alert, and the picker already. Now you have to implement them. You don't fill in data for the picker, the picker asks your delegate for the data.
You need the mandatory functions defined in these three protocols.
UIPickerViewDelegate
UIPickerViewDataSource
UIActionSheetDelegate
You have to implement -(IBAction)dismissActionSheet:(UIButton *)sender too.
and How do I get value when "done" is clicked.
I would store the value to a instance variable every time the picker changes, and once the done button is clicked I would assign it to my data model.
Edit: If you want to learn something I would get rid of the copy&paste solution and try to implement it on my own. But YMMV.
HI all below is the code i am using, the textField is created in .h file and when i run the code the text field doesnt respond to keyboard( no letters typed are visible) also when i click Done on keybpard it does not trigger textfieldshouldreturn method. please help!!!
UIActionSheet *aac =[[UIActionSheet alloc] initWithTitle:#"New list item" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
UIDatePicker *theDatePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0.0,100.0,0.0,0.0)];
self.textField=[[UITextField alloc] init];
self.textField.frame = CGRectMake(12, 45, 260, 25);
[self.textField setDelegate:self];
self.textField.textColor=[UIColor blackColor];
self.textField.backgroundColor=[UIColor whiteColor];
[textField setBorderStyle:UITextBorderStyleRoundedRect];
[textField setReturnKeyType:UIReturnKeyDone];
textField.keyboardType=UIKeyboardAppearanceDefault;
[aac addSubview:textField];
[aac addSubview:theDatePicker];
[textField release];
[theDatePicker release];
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Done"]];
closeButton.momentary=YES;
closeButton.frame = CGRectMake(270, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle=UISegmentedControlStyleBar;
closeButton.tintColor =[UIColor blackColor];
[closeButton addTarget:self action:#selector(dismissActionSheet) forControlEvents:UIControlEventValueChanged];
[aac addSubview:closeButton];
[closeButton release];
[aac showInView:self.view];
[aac setBounds:CGRectMake(0, 0, 320, 685)];
Have you tried removing the self. from before textField? If you have defined it in your header, as well as used #property, and #synthesize in your .m, you should be good. Also, make sure you have the <UITextFieldDelegate> in your interface.
I just had the same problem; My textfield did bring up the keyboard when I touched it, but no letters appeared in the textfield when tapping on the keyboard.
In my case I had been messing with the AppDelegate.m and removed the [self.window makeKeyAndVisible];. So putting it back again (in application:didFinishLaunchingWithOptions:) solved it for me.