Gold Challenge - My Solution (includes Silver and Bronze)


#1

Here’s my solution for the gold challenge. Satisfies all challenge requirements for Gold, Silver and Bronze challenges. :sunglasses:
My classes are prefixed with PSY instead of BNR. Comments and suggestions are welcome, I would not consider myself an Objective-C expert and would appreciate any advice as to anything that may have been done incorrectly or inefficiently.

:ugeek:

note: I have been told by a friend that my code would be better if I had used datasource methods to check for section counts and rows instead of the tableView’s methods, and I certainly could have. But I was feeling lazy and just did everything inline instead.

//
//  PSYItemsViewController.m
//  Homepwner
//
//  Created by Robert Sogomonian on 4/6/14.
//

#import "PSYItemsViewController.h"
#import "PSYItem.h"
#import "PSYItemStore.h"

@interface PSYItemsViewController () <UITableViewDataSource>

@property (nonatomic) BOOL firstSectionEmpty;
@property (nonatomic) BOOL secondSectionEmpty;

@end

@implementation PSYItemsViewController

- (instancetype)init
{
    // Call the superclass's designated initializer
    if (self = [super initWithStyle:UITableViewStyleGrouped]) {
        for (int i = 0; i < 5; i++) {
            [[PSYItemStore sharedStore] createItem];
        }
    }
	
    return self;
}

- (instancetype)initWithStyle:(UITableViewStyle)style
{
    return [self init];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	
	UIImage *imgBackground = [UIImage imageNamed:@"bgImage.jpg"];
	UIView *backgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
	[backgroundView setBackgroundColor:[UIColor colorWithPatternImage:imgBackground]];
	
	self.tableView.backgroundColor = [UIColor clearColor];
	self.tableView.backgroundView = backgroundView;
    
    [self.tableView registerClass:[UITableViewCell class]
           forCellReuseIdentifier:@"UITableViewCell"];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
	// Get an array of the items in the item sharedStore
	NSArray *items = [[PSYItemStore sharedStore] allItems];
	
	// For each item in the items array
	for (PSYItem *item in items) {
		// Check to see if there are any items valued at more than $50
		if (item.valueInDollars > 50) {
			// If there are, we're going to make two sections in this table view
			return 2;
		}
	}
	
	// If there are no items in the items array or if there are no items valued at more than $50
	// we're going to make one section in this table view
	return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
	NSArray *items = [[PSYItemStore sharedStore] allItems];
	int count = 0;
	self.firstSectionEmpty = NO;
	self.secondSectionEmpty = NO;
	
	// For each item in the sharedStore, check to see which section we're in and what the item's value is
	// and if the item's value matches its section, increase the count of the number of rows in section
	for (PSYItem *item in items) {
		if (section == 0 && item.valueInDollars > 50) {
			count++;
		} else if (section == 1 && item.valueInDollars <= 50) {
			count++;
		}
	}
	
	// If no items in each section, mark the sections as empty
	if (count == 0 && section == 0) {
		self.firstSectionEmpty = YES;
	} else if (count == 0 && section == 1) {
		self.secondSectionEmpty = YES;
	}
	
	// If we're in the last section of the current table, create an extra row at the end for an "End of Items" cell
	if ([tableView numberOfSections] == section + 1) {
		count++;
	}
	
    return count;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
	// First section is items more than $50, Second section is items less than or equal to $50
	// Final otherwise, no title
	if (section == 0 && !self.firstSectionEmpty) {
		return @"Items More than $50";
	} else if (section == 1 && !self.secondSectionEmpty) {
		return @"Items Less than or equal to $50";
	} else {
		return @"";
	}
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
	// Get the default row height for the table
	CGFloat height = 60;
	
	// If we're in the last section and at the final row
	if (([tableView numberOfSections] == indexPath.section + 1) && ([self tableView:tableView numberOfRowsInSection:indexPath.section] - 1 == indexPath.row)) {
		height = [tableView rowHeight];
	}
	
	return height;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Create an instance of UITableViewCell, with default appearence
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                            forIndexPath:indexPath];
	cell.backgroundColor = [UIColor clearColor];

	// Set the text on the cell with the description of the item that is at the nth index of items,
    // where n = row this cell will appear in on the tableview
    NSArray *items = [[PSYItemStore sharedStore] allItems];
	NSMutableArray *thisSection = [[NSMutableArray alloc] init];
	
	// If we're in the last row, report no more items
	if (([tableView numberOfSections] == indexPath.section + 1) && ([self tableView:tableView numberOfRowsInSection:indexPath.section] - 1 == indexPath.row)) {
		cell.textLabel.text = @"No more items!";
	} else {
		for (PSYItem *item in items) {
			if (indexPath.section == 0 && item.valueInDollars > 50) {
				[thisSection addObject:item];
			} else if (indexPath.section == 1 && item.valueInDollars <= 50) {
				[thisSection addObject:item];
			}
		}
		
		PSYItem *item = thisSection[indexPath.row];
		cell.textLabel.font = [UIFont systemFontOfSize:20.0];
		cell.textLabel.text = [item description];
	}
    
    return cell;
}

@end

#2

Why is self required in the block after && ?
Why cant one use ([tableView numberOfRowsInSection:IndexPath.section] - 1 == indexPath.row) instead?

   if (([tableView numberOfSections] == indexPath.section + 1) && ([self tableView:tableView numberOfRowsInSection:indexPath.section] - 1 == indexPath.row)) {
      height = [tableView rowHeight];
   }