Silver Challenge Shortest Solution


#1

Here is my solution of the Silver Challenge. I’ve spent around 2hours on the solution pulling my hair out and trying to understand how :wink:. It was worth it!:slight_smile:

#import "BNRAppDelegate.h"
#import "BNRHypnosisView.h"

//conforming the appDelegate to UIScrollViewDelegate protocol
@interface BNRAppDelegate () <UIScrollViewDelegate>
//adding the property of HypnosisView
@property (nonatomic, strong) BNRHypnosisView * cos1;

@end

@implementation BNRAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    
    
    CGRect screenRect = self.window.bounds;
    CGRect bigRect = screenRect;
    
    bigRect.size.width *= 2.0;
    bigRect.size.height *= 2.0;
    
    //create a screen sized scroll view and add it to the view window
    
    UIScrollView * obraz = [[UIScrollView alloc] initWithFrame:screenRect];
    
    
    [self.window addSubview:obraz];
    
   //changed as suggested in the book
    self.cos1 = [[BNRHypnosisView alloc] initWithFrame:bigRect];
    
    [obraz addSubview:self.cos1];
    
    
    
    //tell the scroll view how big is the content size, so it will be possible to scroll the view
    
    obraz.contentSize = bigRect.size;
    

    //SILVER CHALLENGE: set the UIScrollView instance minimum and maximum zoom scale
    obraz.minimumZoomScale = 1;
    obraz.maximumZoomScale = 5;
    //making a delegate
    obraz.delegate = self;
    
    
    
    
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

// SILVER CHALLENGE: Method implemented and inherited from the protocol
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)zo
{
    
    
    NSLog(@"viewForZoomingInScrollView works!!");
    return self.cos1;
    
}
//SILVER CHALLENGE: It works without this method, but the documentation suggested to add this one too
-(void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
    NSLog(@"end it");
}


#2

I liked your solution, helped me a lot to understand how it works.

Also, if you want to center the view at load, add this line to your code:


#3

Thanks man! :slight_smile:


#4

Great help, thank you.


#5

Maybe better insert [quote][obraz addSubview:self.cos1];[/quote] after this block:?

[quote]//tell the scroll view how big is the content size, so it will be possible to scroll the view

obraz.contentSize = bigRect.size;


//SILVER CHALLENGE: set the UIScrollView instance minimum and maximum zoom scale
obraz.minimumZoomScale = 1;
obraz.maximumZoomScale = 5;
//making a delegate
obraz.delegate = self;[/quote]

Or it doesn’t matter?


#6

Thanks for your help, I didn’t really know where to start!
I didn’t understand why you create bigFrame in your code though, except for the BNRHypnosisView to be scaled x2 already when the app starts. Which is not especially what we would like. The bigFrame has actually nothing to do with the zooming, isn’t it ? I also removed the .center option then, as the two views have the same size, their center will be the same.
I also didn’t see the purpose of the contentSize property, as you already input the UIScrollView in the frame, so I deleted it (and the program is still working as we want it to work).

Here is my solution. I didn’t want to erase the tabs, so I put the code in BNRHypnosisViewController instead of the AppDelegate, and here it is:

[code]//
// BNRHypnosisViewController.m
// HypnoNerd
//

#import “BNRHypnosisViewController.h”
#import “BNRHypnosisView.h”

@interface BNRHypnosisViewController () <UITextFieldDelegate, UIScrollViewDelegate>

@property (nonatomic, strong) BNRHypnosisView *backgroundView;

@end

@implementation BNRHypnosisViewController

-(instancetype)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil

-(void)loadView
{
//Create the main view, which will be the UIScrollView view.

//Start by creating a CGRect frame, where we will put the UIScrollView
CGRect frame = [UIScreen mainScreen].bounds;

UIScrollView *scrollViewHypnosis = [[UIScrollView alloc] initWithFrame:frame];

//Let's add the zooming properties of our scroll view.
scrollViewHypnosis.minimumZoomScale = 1;
scrollViewHypnosis.maximumZoomScale = 10;

//Our scroll view is finished, let's now make BNRHypnosisViewController its delegate.
scrollViewHypnosis.delegate = self;

//Now let's create our BNRHypnosisView. It's a bit different than before, as we declared the instance variable backgroundView in the class extension.
self.backgroundView = [[BNRHypnosisView alloc] initWithFrame:frame];

//We make the BNRHypnosisView a subview of the UIScrollView.
[scrollViewHypnosis addSubview:self.backgroundView];

//Then we make the UIScrollView the view of our BNRHypnosisControllerView.
self.view = scrollViewHypnosis;

}

//Now let’s implement the zooming by using the appropriate method

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
NSLog(@“it’s working !”);

//This is the line which explains why we needed the BNRHypnosisView to be declared in the class extension, isn't it ?
return self.backgroundView;

}

@end
[/code]

Any comments are more than welcomed…