Gold challenge problem


I subclassed UIView as follows:-

#import “CrossHairView.h”

@implementation CrossHairView

  • (id)initWithFrame:(CGRect)frame
    self = [super initWithFrame:frame];
    if (self) {
    // Initialization code
    return self;

  • (void)drawRect:(CGRect)rect
    CGRect bounds = self.bounds;
    //get centre
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;

    UIBezierPath *path =[[UIBezierPath alloc] init];

    [path moveToPoint:center];
    CGPoint top;
    top.x = center.x;
    top.y = center.y + 30;

    CGPoint bottom;
    bottom.x = center.x;
    bottom.y = center.y - 30;

    CGPoint right;
    right.x = center.x + 30;
    right.y = center.y;

    CGPoint left;
    left.x = center.x - 30;
    left.y = center.y ;

    [path addLineToPoint:top];
    [path addLineToPoint:bottom];
    [path addLineToPoint:center];
    [path addLineToPoint:left];
    [path addLineToPoint:right];

    path.lineWidth = 4;

    [[UIColor redColor] setStroke];

    [path stroke];


Then I altered takePicture method in BNRDetailViewController

#import “BNRDetailViewController.h”
#import “BNRItem.h”
#import “BNRImageStore.h”
#import “CrossHairView.h”
@interface BNRDetailViewController ()

//inorder to give UIimagePickerConroller the nec delegate must conform to protocol
//note also need UINavigationConrollerDelegate protocol
<UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *serialNumberField;
@property (weak, nonatomic) IBOutlet UITextField *valueField;
@property (weak, nonatomic) IBOutlet UILabel *dateLabel;

@property (weak, nonatomic) IBOutlet UIToolbar *toolbar;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;


//to dismiss keyboard by touching any where else on view
//note changed views class to UIConrol in xib
@implementation BNRDetailViewController

  • (IBAction)deleteImage:(id)sender
    //check if image
    if (self.imageView)
    self.imageView = nil;
    [[BNRImageStore sharedStore] deleteImageForKey:self.item.itemKey];



  • (IBAction)backgroundTapped:(id)sender

    [self.view endEditing:YES];


  • (IBAction)takePicture:(id)sender
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
    //if device has camera take pic
    //else pick from photo lib

    imagePicker.allowsEditing = YES;

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    //put in code to put in crosshairs

      CGRect firstFrame = CGRectMake(0, 0, 320, 480);
      CrossHairView *crossHairs = [[CrossHairView alloc] initWithFrame:firstFrame];
      crossHairs.backgroundColor = [UIColor clearColor];
      imagePicker.cameraOverlayView = crossHairs;

    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    //sets instance of BNRDetailViewController to be imagePickers delegate
    imagePicker.delegate = self;

    //To present image picker modally ie take up all of screen
    //while it is doing its stuff

    [self presentViewController:imagePicker animated:YES completion:nil]; //third argument expects a block


//delegate method to reference photograph
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
UIImage *image;
if (info[UIImagePickerControllerEditedImage])
image = info[UIImagePickerControllerEditedImage];

    image = info[UIImagePickerControllerOriginalImage];

//get picked image from info dictionary
//UIImage *image = info[UIImagePickerControllerOriginalImage];

//store the image in BNRImageStore for items imageKey
[[BNRImageStore sharedStore] setImage:image forKey:self.item.itemKey];

//put image on screen in imageview

self.imageView.image = image;

//take picker off screen using following dismiss method
[self dismissViewControllerAnimated:YES completion:nil];


//overide synthesised setter for item property
-(void)setItem:(BNRItem *)item;
_item = item;
self.navigationItem.title = _item.itemName;

//need to overide viewwillappear
[super viewWillAppear];
BNRItem *item = self.item;

self.nameField.text = item.itemName;
self.serialNumberField.text = item.serialNumber;
self.valueField.text = [NSString stringWithFormat:@"%d",item.valueInDollars];

//need an NSDateFormatter that will turn a date into a simple text string

static NSDateFormatter *dateFormatter = nil;

if (!dateFormatter)
    dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateStyle = NSDateFormatterMediumStyle;
    dateFormatter.timeStyle = NSDateFormatterNoStyle;

self.dateLabel.text =[dateFormatter stringFromDate:item.dateCreated];

// code to populate item image

NSString *imageKey = self.item.itemKey;
//get image from imagestore

UIImage *imageToDisplay = [[BNRImageStore sharedStore] imageForKey];
//use image to put on screen

self.imageView.image = imageToDisplay;

//note if there is no image associated with the key imageForKey will return nil
// then UIImage will not display an image


//implement view will disappera to allow edited values of item to be saved

//v imp - call superclasses implementation!!!
[super viewWillDisappear];
//clear first responder
[self.view endEditing:YES];

//save changes to item
BNRItem *item = self.item;
item.itemName = self.nameField.text;
item.serialNumber = self.serialNumberField.text;
item.valueInDollars = [self.valueField.text intValue];


// to allow this we have set up detailviewcontroller to conform to UiTextFeildDelegateProtocol
-(BOOL)textFieldShouldReturn:(UITextField *)textField
[textField resignFirstResponder];
return YES;



The application runs on I phone, cross hairs appear when camera activates.
After taking picture the application freezes

I would love to know why?


I have read through other posts on this chapter
From these i discovered problem is my cross hair view covers entire screen and therefore buttons in other views are not available when cross hairs is active view.

Easily resolved by shortening cross hair view so it does not cover bottom bar.