Spicy Bronze solution


#1

This has just a bit of a twist to it.

HypnosisterAppDelegate.h

[code]#import <UIKit/UIKit.h>
#import “HypnosisView.h”

@interface HypnosisterAppDelegate : UIResponder <UIApplicationDelegate, UIScrollViewDelegate>
{
HypnosisView *view;
}
@property (strong, nonatomic) UIWindow *window;

@end
[/code]

HypnosisterAppDelegate.m

#import "HypnosisterAppDelegate.h"
#import "HypnosisView.h"

@implementation HypnosisterAppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    
    [[UIApplication sharedApplication] setStatusBarHidden:YES 
                                            withAnimation:UIStatusBarAnimationFade];
    
    CGRect screenRect = [[self window] bounds];
    
    // Create the UIScrollView to have the size of the window, matching its size
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:screenRect];
    
    // Makes the view snap to one of the views
    //[scrollView setPagingEnabled:YES];
    
    [scrollView setMinimumZoomScale:1.0];
    [scrollView setMaximumZoomScale:5.0];
    
    // You will get a warning here, ignore it.
    [scrollView setDelegate:self];
    
    [[self window] addSubview:scrollView];
    
    
    //CGRect viewFrame = CGRectMake(160, 240, 100, 150);
    
    //HypnosisView *view = [[HypnosisView alloc] initWithFrame:viewFrame];
    //HypnosisView *view = [[HypnosisView alloc] initWithFrame:[[self window] bounds]];
    
    // Create the HypnosisView with a frame that is twice the size of the screen
    CGRect bigRect = screenRect;
    //bigRect.size.width *= 2.0;
    //bigRect.size.height *= 2.0;
    //HypnosisView *view = [[HypnosisView alloc] initWithFrame:screenRect];
    view = [[HypnosisView alloc] initWithFrame:screenRect];
    
    // Add the HypnosisView as a subview of the scrollView instead of the window 
    [scrollView addSubview:view];
    
    // Move the rectangle for the other HypnosisView to the right, just off the screen
    //screenRect.origin.x = screenRect.size.width;
    //HypnosisView *anotherView = [[HypnosisView alloc] initWithFrame:screenRect];
    //[scrollView addSubview:anotherView];
    
    // Tell the scrollView how big its virtual world is
    [scrollView setContentSize:bigRect.size];
    
    
    //[view setBackgroundColor:[UIColor redColor]];
    //[[self window] addSubview:view];
    
    BOOL success = [view becomeFirstResponder];
    if (success) {
        NSLog(@"HypnosisView became the first responder");
    } else {
        NSLog(@"Could not become first responder");
    }
    
    //CGRect anotherFrame = CGRectMake(20, 30, 50, 50);
    
    //HypnosisView *anotherView = [[HypnosisView alloc] initWithFrame:anotherFrame];
    
    //[anotherView setBackgroundColor:[UIColor blueColor]];
    //[view addSubview:anotherView];
    
    
    //[[self window] addSubview:anotherView];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return view;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

HypnosisView.h

#import <Foundation/Foundation.h>

@interface HypnosisView : UIView
{
    
}

@property (nonatomic, strong) UIColor *circleColor;

@end

HypnosisView.m

#import "HypnosisView.h"

// generate random float between 0 and 10 not inclusive      Im really not 100% sure of this inclusivity
#define randomFloat1()   arc4random() % 10000 / 10000.0;
#define randomFloat2()   arc4random() % 10000 / 100.0;

@implementation HypnosisView
@synthesize circleColor;


- (void)drawRect:(CGRect)dirtyRect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGRect bounds = [self bounds];
    
    // Figure out the center of the bounds rectangle
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;
    
    // The radius of the circle should be nearly as big as the view
    // float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 4.0;
    float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 2.0;
    
    // the thickness of the line should be 10 points wide
    CGContextSetLineWidth(ctx, 10);
    
    // The color of the line should be gray (red/green/blue = 0.6, alpha = 1.0)
    //CGContextSetRGBStrokeColor(ctx, 0.6, 0.6, 0.6, 1.0);
    
    //[[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:1.0] setStroke];
    
    [[self circleColor] setStroke];
    
    //  Add a shape to the context - this does not draw the shape
   // CGContextAddArc(ctx, center.x, center.y, maxRadius, 0.0, M_PI * 2.0, YES);
    
    // Perform a drawing instruction; draw current shape with current state 
    //CGContextStrokePath(ctx);
    
    // Draw concentric circles from the outside in
    for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
        // Make circles different colors for the bronze challenge
        float flt1 = randomFloat1();
        float flt2 = randomFloat1();
        float flt3 = randomFloat1();
        
        NSLog(@"RGB = (%f, %f, %f)\n\n", flt1, flt2, flt3);
        [[UIColor colorWithRed:flt1 green:flt2 blue:flt3 alpha:1.0] setStroke];
        
        // Add a path to the context
        float diminishoffset = (float)(currentRadius/maxRadius);
        
        float offsetX = 50.0 - randomFloat2();
        float offsetY = 50.0 - randomFloat2();
        
        NSLog(@"diminishoffset = %f offset (x, y) = (%f, %f)\n\n", diminishoffset, offsetX, offsetY);
        CGContextAddArc(ctx, center.x + diminishoffset * offsetX, center.y + diminishoffset * offsetY, currentRadius, 0.0, M_PI * 2.0, YES);
        CGContextSetLineWidth(ctx, 10 * currentRadius / (maxRadius - currentRadius + 1));
        
        // Perform drawing instruction; removes path
        CGContextStrokePath(ctx);
    }
    
    // Create a string 
    NSString *text = @"You are getting sleepy.";
    
    // Get a font to draw it in
    UIFont *font = [UIFont boldSystemFontOfSize:28];
    
    CGRect textRect;
    
    // How big is this string when drawn in this font?
    textRect.size = [text sizeWithFont:font];
    
    // Let's put that string in the center of the view
    textRect.origin.x = center.x - textRect.size.width / 2.0;
    textRect.origin.y = center.y - textRect.size.width / 2.0;
    
    // Set the fill color of the current context to black
    [[UIColor blackColor] setFill];
    
    // The shadow will move 4 points to the right and 3 points down from the text 
    CGSize offset = CGSizeMake(4, 3);
    
    // The shadow will be dark gray in color
    CGColorRef color = [[UIColor darkGrayColor] CGColor];
    
    // Set the shadow of the context with these parameters,
    // all subsequent drawing will be shadowed
    CGContextSetShadowWithColor(ctx, offset, 4.0, color);
    
    // Draw the string 
    [text drawInRect:textRect withFont:font];
    
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // All HypnosisViews start with a clear background color
        [self setBackgroundColor:[UIColor clearColor]];
        [self setCircleColor:[UIColor lightGrayColor]];
    }
    return self;
}


- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake) {
        NSLog(@"Device started shaking!");
        [self setCircleColor:[UIColor redColor]];
    }
}

- (void)setCircleColor:(UIColor *)clr
{
    circleColor = clr;
    [self setNeedsDisplay];
}
@end

#2

That nifty. It would be good to let us know what the outcome will be, so we can try it and verify and examine the code.
FYI, the above code makes random colored circles and also offsets them to the center so they are wobbly-looking and makes the stroke width smaller in the middle and fatter toward the outer side.
I would say it’s creative!
In my solution I kept the ability to shake and turn all the rings red.

HypnosisView.h

[code]#import <Foundation/Foundation.h>
@interface HypnosisView : UIView
{
BOOL isShaking;
}

@property (nonatomic, strong) UIColor *circleColor;
-(float)randomFloat;

@end[/code]

HypnosisView.m
makes a random UIColor, if the isShaking bool is not set to YES. So when it starts, you get random color. When you shake, the red color is set.

[code]#import “HypnosisView.h”
@implementation HypnosisView
@synthesize circleColor;

-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
[self setBackgroundColor:[UIColor clearColor]];
isShaking = NO; //set this var so we know we aren’t shaking
return self;
}

-(BOOL)canBecomeFirstResponder
{
return YES;
}

-(void)setCircleColor:(UIColor *)clr
{
circleColor = clr;
[self setNeedsDisplay];
}

-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (motion == UIEventSubtypeMotionShake) {

NSLog(@"motion sickness");
    isShaking = YES; //now we are shaking, plus set UI color to red
    [self setCircleColor:[UIColor redColor]];
}

}

-(void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect bounds = [self bounds];
NSLog(@“bounds: %3.1f x %f”, bounds.size.width, bounds.size.height);

//draw a circle
CGPoint center;
center.x = bounds.origin.x + bounds.size.width / 2.0;
center.y = bounds.origin.y + bounds.size.height / 2.0;

float maxRadius = hypot(bounds.size.width, bounds.size.height) / 2.0;
CGContextSetLineWidth(ctx, 10);


//draw multiple lines
for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
    CGContextAddArc(ctx, center.x, center.y, currentRadius, 0.0, M_PI * 2.0, YES);
    
    if (!isShaking) //if we are not shaking, then use the rand color generation
    {
    [self setCircleColor:[UIColor colorWithRed:[self randomFloat] 
                                          green:[self randomFloat] 
                                           blue:[self randomFloat] 
                                          alpha:1.0]];
    }
    
    [[self circleColor] setStroke];
    CGContextStrokePath(ctx);
}

NSString *text = @"you are getting sleepy";
UIFont *font = [UIFont boldSystemFontOfSize:28];
CGRect textRect;
//figure out ahead of time how big the text is in specified font
textRect.size = [text sizeWithFont:font];

textRect.origin.x = center.x - textRect.size.width/2.0;
textRect.origin.y = center.y - textRect.size.height/2.0;
[[UIColor blackColor] setFill];

//fancy shadow on text
CGSize offset = CGSizeMake(4, 3);
CGColorRef color = [[UIColor darkGrayColor] CGColor];
CGContextSetShadowWithColor(ctx, offset, 2.0, color);

[text drawInRect:textRect withFont:font];

}

-(float)randomFloat
{
//we want to create a float between 0 and 1
int iseed = rand(); //rand is crappy but we only need any int
srand(iseed); //seed rand with new seed #
int i = rand(); //get a new random int
float x = (float) i / (float) RAND_MAX; //rand_max is 32767 or higher, just a big number to use for division to make a nice float, we could use any constant too
NSLog(@"%f", x);
return x;
}

@end[/code]