Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

David Greenstein
6,734 Pointshelp with self destructive messaging app
for some reason when i run it. the username i click selects the one below the 1 i click and i cant find the error. Additionally, when i press cancel button if i want to cancel sending a photo it is supposed to clear the list of recipients i had checked off and it doesnt. I think the two problems are related. Could anyone help me out with this. I would be extremely grateful.
15 Answers

Stone Preston
42,016 Pointscheck that you implemented the right tableViewDelegate method. It sounds like you implemented
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
instead of
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

Stone Preston
42,016 Pointsas for the clearing checked recipients on cancel, please post the code for your cancel button action.

David Greenstein
6,734 Pointspragma mark - IBActions
-
(IBAction)cancel:(id)sender { self.image = nil; self.videoFilePath = nil; [self.recipients removeAllObjects];
[self.tabBarController setSelectedIndex:0]; }

David Greenstein
6,734 Pointspragma mark - IBActions
- (IBAction)cancel:(id)sender {
self.image = nil;
self.videoFilePath = nil;
[self.recipients removeAllObjects];
[self.tabBarController setSelectedIndex:0];
}

David Greenstein
6,734 Pointsthis is the .h code
import <UIKit/UIKit.h>
import <Parse/Parse.h>
@interface CameraViewController : UITableViewController < UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (nonatomic, strong) UIImagePickerController *imagePicker; @property (nonatomic, strong) UIImage *image; @property (nonatomic, strong) NSString *videoFilePath; @property (nonatomic, strong) NSArray *friends; @property (nonatomic, strong) PFRelation *friendsRelation; @property (nonatomic, strong) NSMutableArray *recipients;
- (IBAction)cancel:(id)sender;
@end

Stone Preston
42,016 Pointstry adding the following line after you call removeAllObjects
[self.tableView reloadData];
that will reload the tableview, and since your recipients list is empty, none of them should be checked.

David Greenstein
6,734 Pointsthat didnt work they are still all checked

Stone Preston
42,016 Pointsok can you post the code for your entire view controller.m please. format the code by going to a new line in your forum post, type three back ticks (they look like this: ` and are located next to the 1 key on your keyboard, skip a line, paste your code, go to a new line, and type three more backticks. it should format it nicely.

David Greenstein
6,734 Pointsdo you want the whole project or whats best for you?

Stone Preston
42,016 Pointswhole project

David Greenstein
6,734 Points//
// CameraViewController.m
// Ribbit
//
// Created by David Greenstein on 2/13/14.
// Copyright (c) 2014 David Greenstein. All rights reserved.
//
#import "CameraViewController.h"
#import <MobileCoreServices/UTCoreTypes.h>
@interface CameraViewController ()
@end
@implementation CameraViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.friendsRelation = [[PFUser currentUser] objectForKey:@"friendsRelation"];
self.recipients = [[NSMutableArray alloc] init];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
PFQuery *query = [self.friendsRelation query];
[query orderByAscending:@"username"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"Error %@ %@", error, [error userInfo]);
}
else {
self.friends = objects;
[self.tableView reloadData];
}
}];
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing = NO;
self.imagePicker.videoMaximumDuration = 10;
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera]) {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else {
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
self.imagePicker.mediaTypes = [UIImagePickerController
availableMediaTypesForSourceType:self.imagePicker.sourceType];
[self presentViewController:self.imagePicker animated:NO completion:nil];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.friends count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user = [self.friends objectAtIndex:indexPath.row];
cell.textLabel.text = user.username;
return cell;
}
#pragma mark - Table View delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)
indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell =[self.tableView cellForRowAtIndexPath:indexPath];
PFUser *user = [self.friends objectAtIndex:indexPath.row];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.recipients addObject:user.objectId];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.recipients removeObject:user.objectId];
}
}
#pragma mark - Image Picker Controller delegate
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:NO completion:nil];
[self.tabBarController setSelectedIndex:0];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
// a photo was taken/selected!
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// save the image
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
else {
// A video was taken/sleected!
NSURL *imagePickerURL = [info objectForKey:UIImagePickerControllerMediaURL];
self.videoFilePath = [imagePickerURL path];
if (self.imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// save the video
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(self.videoFilePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(self.videoFilePath, nil, nil, nil);
}
}
}
}
#pragma mark - IBActions
- (IBAction)cancel:(id)sender {
self.image = nil;
self.videoFilePath = nil;
[self.recipients removeAllObjects];
[self.tableView reloadData];
[self.tabBarController setSelectedIndex:0];
}
@end

Stone Preston
42,016 Pointshmm everything looks good. go ahead and share a dropbox link with me and ill take a look again.

David Greenstein
6,734 Pointshttps://www.dropbox.com/s/vcbz72atphnr1hq/Ribbit.zip
here it is ignroe the send button at the bottom of viewcameracontroller.m just started working on that but has no effect on the simulation. youll see when you run it

David Greenstein
6,734 Pointsdid you find anything?

Stone Preston
42,016 Pointsyes one sec

David Greenstein
6,734 Pointsif possible try to explain over here rather than sending it back because i cant switch documents

Stone Preston
42,016 PointsDavid Greenstein. You need to add the following to your cellForRowAtIndexPath method BEFORE the return Cell statement:
if([self.recipients containsObject:user.objectId]) {
//user is a recipient
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
im not sure if you just missed this part of the video or are getting ahead of yourself. but that should fix it

David Greenstein
6,734 Pointswhere do i place this in my code

Stone Preston
42,016 Pointsinside the cellForRowAtIndexPathMethod before the return cell;
so it should look like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user = [self.friends objectAtIndex:indexPath.row];
cell.textLabel.text = user.username;
if([self.recipients containsObject:user.objectId]) {
//user is a recipient
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}

David Greenstein
6,734 Pointsthank you so much unreal