Multiselect table view controller items for email attachment - objective-c

Here is my XCode 4.3.2 problem... I have a table displaying multi-select NSArray data in a table controller. I would like to select multiple items in the table, click a button on the bottom of the view controller, and attach the selected documents in the project that are referenced in the table's NSArray to an email message. I have the email portion working ok, but not attaching anything. I also have the multi-select check marks working correctly. Any ideas on getting multi-select attachment accomplished? I assume I have to build a mutableArray in which the table data cell text = the local PDF file name.???
Here is some of my code that I think will have to be edited for building the array?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedIndexes addObject:[NSNumber numberWithInt:indexPath.row]];
NSLog(#"Items I selected # %d:", indexPath.row);
NSLog(#"Items I selected: %#", selectedIndexes);
} else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[selectedIndexes removeObject:[NSNumber numberWithInt:indexPath.row]];
NSLog(#"Items I de-selected # %d:", indexPath.row);
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
The mail component:
- (IBAction)sendMailButton:(id)sender {
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"Documentation Attached"];
[mailer setMessageBody:#"Attached are documents from staff." isHTML:NO];
//[mailer setMessageBody:emailBody isHTML:NO];
//iPad presentation enhancement:
mailer.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentModalViewController:mailer animated:YES];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Your device doesn't support the composer sheet"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
}

Related

Two Alertviews on one view [duplicate]

This question already has answers here:
Two Alert Views in One View Controller - buttonIndex Response
(4 answers)
Closed 7 years ago.
EDIT:
Problem Solved ==> Simply giving a tag solved the problem.
I have the following problem:
On a view I have two UIalertviews:
NSString *message = [NSString stringWithFormat:#"Users must enter this code to join the meeting: %#", meetingCode];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Meeting code"
message:message
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"Copy to clipboard", nil];
[alert show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == [alertView cancelButtonIndex])
{
NSLog(#"Code not copied");
}
else
{
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = meetingCode;
NSLog(#"Code copied");
}
}
and this one:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
AgendaModel* agenda = _meeting.agenda[indexPath.row] ;
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:agenda.id,#"id",agenda.name,#"name", nil];
NSString *message = [NSString stringWithFormat:#"Are you sure that you want to delete : %#?", agenda.name];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning"
message:message
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:#"Delete", nil];
[alert show];
NSString *delete_url = [NSString stringWithFormat:#"RestAgendas/delete.json"];
[_meeting.agenda removeObject:agenda];
[self.tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[JSONAPI getWithPath:delete_url andParams:dict completion:^(id json, JSONModelError *err) {
NSLog(#"%#", json);
}];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == [alertView cancelButtonIndex])
{
NSLog(#"Agenda Won't Be Deleted");
}
else
{
NSLog(#"Agenda Will Be Deleted");
}
}
Now is the problem that I got the error: Duplicate declaration of method 'alertView:clickedButtonAtIndex'
How can I fix this? I tried some stuff I found here but I still can't make it work. Can someone help me?
Yep, like you said, giving a tag allows you to have multiple UIAlertView in one single view.
Same goes for UIActionSheet or UIAlertController
for future reference, even though this is probably a duplicate, simply create your alert like usual and add
myAlert.tag = 123; //any number of your choice
and in alertView:clickedButtonAtIndex
you can find it using a switch or some if's
if (alertview.tag = 123){
// this is my alert
}else if(alertview.tag = 333){
// this is my other alert
}
For what it's worth, I suggest using else if and not just if to avoid the whole method to be read everytime, and order your if's by decreasing likeliness of being called.
Note you can also give tags to buttons, views, cells, labels, and just pretty much every outlet you can find.

reload data in TableView after inserting data through web service

I am using JSON parsing to upload data in UITableView. Everything is working fine but after inserting data through textView it's uploading on server but it's not refreshing in my previous and current UITableView. I need to restart my project to see the uploaded data. I want to reload my UITableView after inserting data. I used [self.myTableView reloadData] but it's not working anywhere.
-(PrayerListCustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
PrayerListCustomCell *cell = (PrayerListCustomCell *)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:#"PrayerListCustomCell"
owner:self options:nil]objectAtIndex:0];
}
cell.dateLbl.text = [dateList objectAtIndex:indexPath.row];
cell.prayerLbl.text = [prayerList objectAtIndex:indexPath.row];
return cell;
}
-(void)submitClicked
{
if ([prayerTextView.text isEqualToString:#""]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Please fill
your request in text box!" delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alert show];
}
else
{
prayerSubmitData = prayerTextView.text;
SubmitPrayer *submit = [[SubmitPrayer alloc]init];
[ASKevrOperationManager submitPrayer:submit handler:^(id object , NSError *error
, BOOL success)
{
if (success) {
NSLog(#"this is request data = %#",object);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:#"Successful upload!" delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
prayerTextView.text = #"";
[self.requestTableView reloadData];
//Do refreshment code
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:#"Please try again later!" delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
} ];
}
}
You need to add your committed data into your prayerList array. This should be something like this:
if (success) {
// show alert
[prayerList addObject:prayerTextView.text];
[self.requestTableView reloadData];
prayerTextView.text = #"";
//Do refreshment code
}

didSelectRowAtIndexPath - colorText change not updated instantaneously

I'm trying to change the text color in a custom label in a custom UITableViewCell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//////////////////////
// Unselect the prevoius selected Cell and select this one
WSLanguageTableViewCell *aPreviousSelectedCell= (WSLanguageTableViewCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedRow inSection:0]];
aPreviousSelectedCell.languageLabel.textColor = [UIColor lightGrayColor];
// Select the new one
WSLanguageTableViewCell *aSelectedCell = (WSLanguageTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
aSelectedCell.languageLabel.textColor = [UIColor colorLanguageCellLanguageLabelText];
selectedRow = indexPath.row;
///////////////////////
// Get the new language
PFObject* languageObject = [self.objects objectAtIndex:indexPath.row];
NSString* language = [languageObject objectForKey:kWSLanguageNameKey];
//////////////////////
// Check if it's setup -- if not, then show alert
if (![[languageObject objectForKey:kWSLanguageIsSetupKey] boolValue]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:kPromptChangeLanguageNotSetup message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
return;
}
//////////////////////
// Check if it's the current language -- only change if not
if (![language isEqualToString:[[WSWordlistManager shared] languageTarget]]) {
// Show HUD view
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[appDel showGlobalProgressHUDWithTitle:kLocalizedChangingLanguage];
//////////////////////
// Load the wordlist
[[WSWordlistManager shared] loadWordlist:language completion:^() {
//////////////////////
// Add the language to user (and vice versa) in DB
[WSUserManager addLanguage:language forUser:[PFUser currentUser]];
///////////////////
// Reload User Words
WSDatabaseManager* databaseManager = [[WSDatabaseManager alloc] init];
[databaseManager retrieveUserWordlistForCurrentUserWithCallback:^(NSError *error) {
// Dismiss the HUD
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[appDel dismissGlobalHUD];
// Navigate to root
[self.navigationController popToRootViewControllerAnimated:YES];
}];
}];
}
}
The problem is, the color change is delayed for a while. If I take out everything below the 6 lines setting the textColor of the two cells, the change is instantaneous. What method(s) do I run right after changing the textColor so it displays?
Check UILabel's highlightedTextColor property. This is correct way to change color of selected cell's label.

Undeclared identifier 'mailComposeController'

Here is my .m code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *emailCell = [tableView cellForRowAtIndexPath:indexPath];
if ([emailCell.textLabel.text isEqualToString:#"Contact Developer"]) {
NSLog(#"Email button pressed...");
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"A Message from MobileTuts+"];
NSArray *toRecipients = [NSArray arrayWithObjects:#"fisrtMail#example.com", #"secondMail#example.com", nil];
[mailer setToRecipients:toRecipients];
NSString *emailBody = #"Have you seen the MobileTuts+ web site?";
[mailer setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:mailer animated:YES];
[mailer release];
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled: you cancelled the operation and no email message was queued.");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved: you saved the email message in the drafts folder.");
break;
case MFMailComposeResultSent:
NSLog(#"Mail send: the email message is queued in the outbox. It is ready to send.");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail failed: the email message was not saved or queued, possibly due to an error.");
break;
default:
NSLog(#"Mail not sent.");
break;
}
// Remove the mail view
[self dismissModalViewControllerAnimated:YES];
}
}
else {
UIAlertView *emailAlert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:#"Please make sure you have an email address configured in your Mail app."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[emailAlert show];
[emailAlert release];
}
}
}
I have imported everything correctly in .h and .m, but the email won't close... I have tried as suggested on Stack Overflow to fiddle with the mailer.mailComposeDelegate = self; but I am still getting an undeclared identifier error. How do I fix this? Thanks.
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
Move this function out of the tableview delegate method. You should learn some basics. You cannot have a method within another method. If you need then you can call the method by [self callingFunctionName];
In you case,
if ([emailCell.textLabel.text isEqualToString:#"Contact Developer"]) {
NSLog(#"Email button pressed...");
[self sendEmail];
}
-(void)sendEmail{
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"A Message from MobileTuts+"];
NSArray *toRecipients = [NSArray arrayWithObjects:#"fisrtMail#example.com", #"secondMail#example.com", nil];
[mailer setToRecipients:toRecipients];
NSString *emailBody = #"Have you seen the MobileTuts+ web site?";
[mailer setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:mailer animated:YES];
[mailer release];
}
}
This will open the mail composer. When you send, cancel or save the mail, the delegate function
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
will automatically be called.

Unable to handle setEditing method through UIBarButtonItem

I have added a bar button item in my tool bar and I implemented its functionality in the method given below. I am not able, however, to display a delete button in each row. How can I do this?
-(void)setEditing:(BOOL)editing
animated:(BOOL)animated
{
[super setEditing:editing
animated:animated];
[editButton setEnabled:!editing];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSString *selectedFile = (NSString*) [directoryContents objectAtIndex: indexPath.row];
NSString *selectedPath = [directoryPath stringByAppendingPathComponent:selectedFile];
BOOL canWrite = [[NSFileManager defaultManager] isWritableFileAtPath:selectedPath];
if(!canWrite)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"status"
message:#"path isnt writable"
delegate:nil
cancelButtonTitle:#"cancel"
otherButtonTitles:nil];
[alert show];
[alert release];
}
NSError *err = nil;
if(! [[NSFileManager defaultManager] removeItemAtPath:selectedPath error:&err])
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"status"
message:#"cannot delete"
delegate:nil
cancelButtonTitle:#"cancel"
otherButtonTitles:nil];
[alert1 show];
[alert1 release];
}
// Delete the row from the data source.
NSArray *deletedPaths = [NSArray arrayWithObject: indexPath];
[self loadDirectoryContents];
[self.tableview deleteRowsAtIndexPaths:deletedPaths withRowAnimation:YES];
}
}
The button on the toolbar will need to be connected to an interface action in the custom table view controller subclass. Define the action as follows -
- (IBAction)startEditing {
[self setEditing:YES animated:YES];
}
-(void)setEditing:(BOOL)editing
animated:(BOOL)animated
{
[super setEditing:editing
animated:animated];
[editButton setEnabled:!editing];
}
You will have to implement the delegate method tableView:editingStyleForRowAtIndexPath and return UITableViewCellEditingStyleDelete for the rows you wish to enable it.