123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- //
- // SinaWeiboAuthorizeView.m
- // sinaweibo_ios_sdk
- //
- // Created by Wade Cheng on 4/19/12.
- // Copyright (c) 2012 SINA. All rights reserved.
- //
- #import "SinaWeiboAuthorizeView.h"
- #import "SinaWeiboRequest.h"
- #import "SinaWeibo.h"
- #import "SinaWeiboConstants.h"
- #import <QuartzCore/QuartzCore.h>
- static CGFloat kBorderGray[4] = {0.3, 0.3, 0.3, 0.8};
- static CGFloat kBorderBlack[4] = {0.3, 0.3, 0.3, 1};
- static CGFloat kTransitionDuration = 0.3;
- static CGFloat kPadding = 0;
- static CGFloat kBorderWidth = 10;
- @implementation SinaWeiboAuthorizeView
- @synthesize delegate;
- #pragma mark - Drawing
- - (void)addRoundedRectToPath:(CGContextRef)context rect:(CGRect)rect radius:(float)radius
- {
- CGContextBeginPath(context);
- CGContextSaveGState(context);
-
- if (radius == 0)
- {
- CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
- CGContextAddRect(context, rect);
- }
- else
- {
- rect = CGRectOffset(CGRectInset(rect, 0.5, 0.5), 0.5, 0.5);
- CGContextTranslateCTM(context, CGRectGetMinX(rect)-0.5, CGRectGetMinY(rect)-0.5);
- CGContextScaleCTM(context, radius, radius);
- float fw = CGRectGetWidth(rect) / radius;
- float fh = CGRectGetHeight(rect) / radius;
-
- CGContextMoveToPoint(context, fw, fh/2);
- CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
- CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
- CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
- CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
- }
-
- CGContextClosePath(context);
- CGContextRestoreGState(context);
- }
- - (void)drawRect:(CGRect)rect fill:(const CGFloat*)fillColors radius:(CGFloat)radius
- {
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
-
- if (fillColors)
- {
- CGContextSaveGState(context);
- CGContextSetFillColor(context, fillColors);
- if (radius)
- {
- [self addRoundedRectToPath:context rect:rect radius:radius];
- CGContextFillPath(context);
- }
- else
- {
- CGContextFillRect(context, rect);
- }
- CGContextRestoreGState(context);
- }
-
- CGColorSpaceRelease(space);
- }
- - (void)strokeLines:(CGRect)rect stroke:(const CGFloat*)strokeColor
- {
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
-
- CGContextSaveGState(context);
- CGContextSetStrokeColorSpace(context, space);
- CGContextSetStrokeColor(context, strokeColor);
- CGContextSetLineWidth(context, 1.0);
-
- {
- CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y-0.5},
- {rect.origin.x+rect.size.width, rect.origin.y-0.5}};
- CGContextStrokeLineSegments(context, points, 2);
- }
- {
- CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y+rect.size.height-0.5},
- {rect.origin.x+rect.size.width-0.5, rect.origin.y+rect.size.height-0.5}};
- CGContextStrokeLineSegments(context, points, 2);
- }
- {
- CGPoint points[] = {{rect.origin.x+rect.size.width-0.5, rect.origin.y},
- {rect.origin.x+rect.size.width-0.5, rect.origin.y+rect.size.height}};
- CGContextStrokeLineSegments(context, points, 2);
- }
- {
- CGPoint points[] = {{rect.origin.x+0.5, rect.origin.y},
- {rect.origin.x+0.5, rect.origin.y+rect.size.height}};
- CGContextStrokeLineSegments(context, points, 2);
- }
-
- CGContextRestoreGState(context);
-
- CGColorSpaceRelease(space);
- }
- - (void)drawRect:(CGRect)rect
- {
- [self drawRect:rect fill:kBorderGray radius:0];
-
- CGRect webRect = CGRectMake(
- ceil(rect.origin.x+kBorderWidth), ceil(rect.origin.y+kBorderWidth)+1,
- rect.size.width-kBorderWidth*2, rect.size.height-(1+kBorderWidth*2));
-
- [self strokeLines:webRect stroke:kBorderBlack];
- }
- #pragma mark - Memory management
- - (id)init
- {
- if ((self = [super init]))
- {
- self.backgroundColor = [UIColor clearColor];
- self.autoresizesSubviews = YES;
- self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- self.contentMode = UIViewContentModeRedraw;
-
- webView = [[UIWebView alloc] init];
- webView.delegate = self;
- webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- [self addSubview:webView];
- [webView release];
-
- UIImage* closeImage = [UIImage imageNamed:@"SinaWeibo.bundle/images/close.png"];
- UIColor* color = [UIColor colorWithRed:167.0/255 green:184.0/255 blue:216.0/255 alpha:1];
- closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
- [closeButton setImage:closeImage forState:UIControlStateNormal];
- [closeButton setTitleColor:color forState:UIControlStateNormal];
- [closeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
- [closeButton addTarget:self action:@selector(cancel)
- forControlEvents:UIControlEventTouchUpInside];
- closeButton.titleLabel.font = [UIFont boldSystemFontOfSize:12];
- closeButton.showsTouchWhenHighlighted = YES;
- closeButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
- [self addSubview:closeButton];
-
- indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:
- UIActivityIndicatorViewStyleGray];
- indicatorView.autoresizingMask =
- UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
- | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
- [self addSubview:indicatorView];
-
- modalBackgroundView = [[UIView alloc] init];
- }
-
- return self;
- }
- - (void)dealloc
- {
- [authParams release], authParams = nil;
- [appRedirectURI release], appRedirectURI = nil;
- [modalBackgroundView release], modalBackgroundView = nil;
-
- [super dealloc];
- }
- - (id)initWithAuthParams:(NSDictionary *)params
- delegate:(id<SinaWeiboAuthorizeViewDelegate>)_delegate
- {
- if ((self = [self init]))
- {
- self.delegate = _delegate;
- authParams = [params copy];
- appRedirectURI = [[authParams objectForKey:@"redirect_uri"] retain];
- }
- return self;
- }
- #pragma mark - View orientation
- - (BOOL)shouldRotateToOrientation:(UIInterfaceOrientation)orientation
- {
- if (orientation == previousOrientation)
- {
- return NO;
- }
- else
- {
- return orientation == UIInterfaceOrientationPortrait
- || orientation == UIInterfaceOrientationPortraitUpsideDown
- || orientation == UIInterfaceOrientationLandscapeLeft
- || orientation == UIInterfaceOrientationLandscapeRight;
- }
- }
- - (CGAffineTransform)transformForOrientation
- {
- UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
- if (orientation == UIInterfaceOrientationLandscapeLeft)
- {
- return CGAffineTransformMakeRotation(M_PI*1.5);
- }
- else if (orientation == UIInterfaceOrientationLandscapeRight)
- {
- return CGAffineTransformMakeRotation(M_PI/2);
- }
- else if (orientation == UIInterfaceOrientationPortraitUpsideDown)
- {
- return CGAffineTransformMakeRotation(-M_PI);
- }
- else
- {
- return CGAffineTransformIdentity;
- }
- }
- - (void)sizeToFitOrientation:(BOOL)transform
- {
- if (transform)
- {
- self.transform = CGAffineTransformIdentity;
- }
-
- CGRect frame = [UIScreen mainScreen].applicationFrame;
- CGPoint center = CGPointMake(frame.origin.x + ceil(frame.size.width/2),
- frame.origin.y + ceil(frame.size.height/2));
-
- CGFloat scaleFactor = SinaWeiboIsDeviceIPad() ? 0.6f : 1.0f;
-
- CGFloat width = floor(scaleFactor * frame.size.width) - kPadding * 2;
- CGFloat height = floor(scaleFactor * frame.size.height) - kPadding * 2;
-
- previousOrientation = [UIApplication sharedApplication].statusBarOrientation;
- if (UIInterfaceOrientationIsLandscape(previousOrientation))
- {
- self.frame = CGRectMake(kPadding, kPadding, height, width);
- }
- else
- {
- self.frame = CGRectMake(kPadding, kPadding, width, height);
- }
- self.center = center;
-
- if (transform)
- {
- self.transform = [self transformForOrientation];
- }
- }
- - (void)updateWebOrientation
- {
- UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
- if (UIInterfaceOrientationIsLandscape(orientation))
- {
- [webView stringByEvaluatingJavaScriptFromString:
- @"document.body.setAttribute('orientation', 90);"];
- }
- else
- {
- [webView stringByEvaluatingJavaScriptFromString:
- @"document.body.removeAttribute('orientation');"];
- }
- }
- #pragma mark - UIDeviceOrientationDidChangeNotification Methods
- - (void)deviceOrientationDidChange:(id)object
- {
- UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
- if ([self shouldRotateToOrientation:orientation])
- {
- NSTimeInterval duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
-
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:duration];
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [self sizeToFitOrientation:orientation];
- [UIView commitAnimations];
- }
- }
- #pragma mark - Animation
- - (void)bounce1AnimationStopped
- {
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:kTransitionDuration/2];
- [UIView setAnimationDelegate:self];
- [UIView setAnimationDidStopSelector:@selector(bounce2AnimationStopped)];
- self.transform = CGAffineTransformScale([self transformForOrientation], 0.9, 0.9);
- [UIView commitAnimations];
- }
- - (void)bounce2AnimationStopped
- {
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:kTransitionDuration/2];
- self.transform = [self transformForOrientation];
- [UIView commitAnimations];
- }
- #pragma mark Obeservers
- - (void)addObservers
- {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(deviceOrientationDidChange:)
- name:@"UIDeviceOrientationDidChangeNotification" object:nil];
- }
- - (void)removeObservers
- {
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:@"UIDeviceOrientationDidChangeNotification" object:nil];
- }
- #pragma mark - Activity Indicator
- - (void)showIndicator
- {
- [indicatorView sizeToFit];
- [indicatorView startAnimating];
- indicatorView.center = webView.center;
- }
- - (void)hideIndicator
- {
- [indicatorView stopAnimating];
- }
- #pragma mark - Show / Hide
- - (void)load
- {
- NSString *authPagePath = [SinaWeiboRequest serializeURL:kSinaWeiboWebAuthURL
- params:authParams httpMethod:@"GET"];
- [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:authPagePath]]];
- }
- - (void)showWebView
- {
- UIWindow* window = [UIApplication sharedApplication].keyWindow;
- if (!window)
- {
- window = [[UIApplication sharedApplication].windows objectAtIndex:0];
- }
- modalBackgroundView.frame = window.frame;
- [modalBackgroundView addSubview:self];
- [window addSubview:modalBackgroundView];
-
- self.transform = CGAffineTransformScale([self transformForOrientation], 0.001, 0.001);
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:kTransitionDuration/1.5];
- [UIView setAnimationDelegate:self];
- [UIView setAnimationDidStopSelector:@selector(bounce1AnimationStopped)];
- self.transform = CGAffineTransformScale([self transformForOrientation], 1.1, 1.1);
- [UIView commitAnimations];
- }
- - (void)show
- {
- [self load];
- [self sizeToFitOrientation:NO];
-
- CGFloat innerWidth = self.frame.size.width - (kBorderWidth+1)*2;
- [closeButton sizeToFit];
- closeButton.frame = CGRectMake(2, 2, 29, 29);
-
- webView.frame = CGRectMake(kBorderWidth+1, kBorderWidth+1, innerWidth,
- self.frame.size.height - (1 + kBorderWidth*2));
-
- [self showWebView];
- [self showIndicator];
-
- [self addObservers];
- }
- - (void)_hide
- {
- [self removeFromSuperview];
- [modalBackgroundView removeFromSuperview];
- }
- - (void)hide
- {
- [self removeObservers];
-
- [webView stopLoading];
-
- [self performSelectorOnMainThread:@selector(_hide) withObject:nil waitUntilDone:NO];
- }
- - (void)cancel
- {
- [self hide];
- [delegate authorizeViewDidCancel:self];
- }
- #pragma mark - UIWebView Delegate
- - (void)webViewDidFinishLoad:(UIWebView *)aWebView
- {
- [self hideIndicator];
- }
- - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
- {
- [self hideIndicator];
- }
- - (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
- {
- NSString *url = request.URL.absoluteString;
- NSLog(@"url = %@", url);
-
- NSString *siteRedirectURI = [NSString stringWithFormat:@"%@%@", kSinaWeiboSDKOAuth2APIDomain, appRedirectURI];
-
- if ([url hasPrefix:appRedirectURI] || [url hasPrefix:siteRedirectURI])
- {
- NSString *error_code = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error_code"];
-
- if (error_code)
- {
- NSString *error = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error"];
- NSString *error_uri = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error_uri"];
- NSString *error_description = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"error_description"];
-
- NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
- error, @"error",
- error_uri, @"error_uri",
- error_code, @"error_code",
- error_description, @"error_description", nil];
-
- [self hide];
- [delegate authorizeView:self didFailWithErrorInfo:errorInfo];
- }
- else
- {
- NSString *code = [SinaWeiboRequest getParamValueFromUrl:url paramName:@"code"];
- if (code)
- {
- [self hide];
- [delegate authorizeView:self didRecieveAuthorizationCode:code];
- }
- }
-
- return NO;
- }
-
- return YES;
- }
- @end
|