Authored by 孟顺

添加引导页 review by jianqiu

... ... @@ -178,6 +178,8 @@
D962AC1A1D30C4E2007834D4 /* messageArrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D962AC181D30C4E2007834D4 /* messageArrow@2x.png */; };
D962AC1B1D30C4E2007834D4 /* messageArrow@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D962AC191D30C4E2007834D4 /* messageArrow@3x.png */; };
EFF834691CEB638B00345113 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A09B25741CE57CA000E68E28 /* CoreTelephony.framework */; };
F9C6B3E91D73E03600B0574C /* SMPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C6B3E81D73E03600B0574C /* SMPageControl.m */; };
F9C6B3EC1D73E05300B0574C /* YH_GuideViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C6B3EB1D73E05300B0574C /* YH_GuideViewController.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
... ... @@ -474,6 +476,10 @@
DF5CC49E6ACE4D402D22806C /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
E02A0042E44F888A50E7158C /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
EF14E52B1C884C71002F1BEF /* YohoLive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YohoLive.app; sourceTree = BUILT_PRODUCTS_DIR; };
F9C6B3E71D73E03600B0574C /* SMPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMPageControl.h; sourceTree = "<group>"; };
F9C6B3E81D73E03600B0574C /* SMPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMPageControl.m; sourceTree = "<group>"; };
F9C6B3EA1D73E05300B0574C /* YH_GuideViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_GuideViewController.h; sourceTree = "<group>"; };
F9C6B3EB1D73E05300B0574C /* YH_GuideViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_GuideViewController.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
... ... @@ -557,6 +563,7 @@
2E4D5FBF1D057BD800D508BB /* Classes */ = {
isa = PBXGroup;
children = (
F9C6B3E61D73E00100B0574C /* Guide */,
2E487B2F1D66B2FB009DBB6D /* YH_Log.h */,
2E487B301D66B2FB009DBB6D /* YH_Log.m */,
2E487AE71D66ADB8009DBB6D /* UtilsMacros.h */,
... ... @@ -952,6 +959,17 @@
name = Framework;
sourceTree = "<group>";
};
F9C6B3E61D73E00100B0574C /* Guide */ = {
isa = PBXGroup;
children = (
F9C6B3E71D73E03600B0574C /* SMPageControl.h */,
F9C6B3E81D73E03600B0574C /* SMPageControl.m */,
F9C6B3EA1D73E05300B0574C /* YH_GuideViewController.h */,
F9C6B3EB1D73E05300B0574C /* YH_GuideViewController.m */,
);
name = Guide;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
... ... @@ -1211,6 +1229,8 @@
2EB6706C1D1908F600E91AAE /* Localisator.m in Sources */,
2E7FDB9A1D52F050005834F8 /* YH_Tool.m in Sources */,
2EB66FF91D18EF2F00E91AAE /* MTLModel+NSCoding.m in Sources */,
F9C6B3E91D73E03600B0574C /* SMPageControl.m in Sources */,
F9C6B3EC1D73E05300B0574C /* YH_GuideViewController.m in Sources */,
2E487B081D66B05F009DBB6D /* YH_DNSUtils.m in Sources */,
2EB66FF81D18EF2F00E91AAE /* MTLManagedObjectAdapter.m in Sources */,
2E487B0D1D66B05F009DBB6D /* YH_H5URLProtocol.m in Sources */,
... ...
... ... @@ -15,8 +15,15 @@
#define BUGLY_APP_ID @"900026972"
#import "YH_RootViewController.h"
#import "YH_GuideViewController.h"
#define YOHO_PUSH_LIVE_GUIDE_FLAG @"YOHO_PUSH_LIVE_GUIDE_FLAG"//引导页是否加载过的标志
@interface AppDelegate ()
@property (strong, nonatomic) YH_GuideViewController *guideVC;
@end
@implementation AppDelegate
... ... @@ -39,10 +46,39 @@
self.window.rootViewController = nc;
if (![[NSUserDefaults standardUserDefaults] boolForKey:YOHO_PUSH_LIVE_GUIDE_FLAG]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:YOHO_PUSH_LIVE_GUIDE_FLAG];
[vc.view addSubview:self.guideVC.view];
[vc addChildViewController:self.guideVC];
[vc.view bringSubviewToFront:self.guideVC.view];
}
[self.window makeKeyAndVisible];
return YES;
}
- (YH_GuideViewController *)guideVC
{
if (!_guideVC) {
_guideVC = [[YH_GuideViewController alloc] init];
__weak typeof(self) weakSelf = self;
_guideVC.block = ^ {
__strong typeof(weakSelf) strongSelf = weakSelf;
if ([strongSelf.guideVC.view superview]) {
[UIView animateWithDuration:0.35 animations:^{
strongSelf.guideVC.view.alpha = 0;
} completion:^(BOOL finished) {
[strongSelf.guideVC.view removeFromSuperview];
}];
}
};
}
return _guideVC;
}
- (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.
... ...
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "guide_1@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "guide_1@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "guide_2@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "guide_2@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "guide_3@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "guide_3@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "guide_4@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "guide_4@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
//
// SMPageControl.h
// SMPageControl
//
// Created by Jerry Jones on 10/13/12.
// Copyright (c) 2012 Spaceman Labs. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, SMPageControlAlignment) {
SMPageControlAlignmentLeft = 1,
SMPageControlAlignmentCenter,
SMPageControlAlignmentRight
};
typedef NS_ENUM(NSUInteger, SMPageControlVerticalAlignment) {
SMPageControlVerticalAlignmentTop = 1,
SMPageControlVerticalAlignmentMiddle,
SMPageControlVerticalAlignmentBottom
};
typedef NS_ENUM(NSUInteger, SMPageControlTapBehavior) {
SMPageControlTapBehaviorStep = 1,
SMPageControlTapBehaviorJump
};
@interface SMPageControl : UIControl
@property (nonatomic) NSInteger numberOfPages;
@property (nonatomic) NSInteger currentPage;
@property (nonatomic) CGFloat indicatorMargin UI_APPEARANCE_SELECTOR; // deafult is 10
@property (nonatomic) CGFloat indicatorDiameter UI_APPEARANCE_SELECTOR; // deafult is 6
@property (nonatomic) CGFloat minHeight UI_APPEARANCE_SELECTOR; // default is 36, cannot be less than indicatorDiameter
@property (nonatomic) SMPageControlAlignment alignment UI_APPEARANCE_SELECTOR; // deafult is Center
@property (nonatomic) SMPageControlVerticalAlignment verticalAlignment UI_APPEARANCE_SELECTOR; // deafult is Middle
@property (nonatomic, strong) UIImage *pageIndicatorImage UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong) UIImage *pageIndicatorMaskImage UI_APPEARANCE_SELECTOR; // ignored if pageIndicatorImage is set
@property (nonatomic, strong) UIColor *pageIndicatorTintColor UI_APPEARANCE_SELECTOR; // ignored if pageIndicatorImage is set
@property (nonatomic, strong) UIImage *currentPageIndicatorImage UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong) UIColor *currentPageIndicatorTintColor UI_APPEARANCE_SELECTOR; // ignored if currentPageIndicatorImage is set
@property (nonatomic) BOOL hidesForSinglePage; // hide the the indicator if there is only one page. default is NO
@property (nonatomic) BOOL defersCurrentPageDisplay; // if set, clicking to a new page won't update the currently displayed page until -updateCurrentPageDisplay is called. default is NO
@property (nonatomic) SMPageControlTapBehavior tapBehavior; // SMPageControlTapBehaviorStep provides an increment/decrement behavior exactly like UIPageControl. SMPageControlTapBehaviorJump allows specific pages to be selected by tapping their respective indicator. Default is SMPageControlTapBehaviorStep
- (void)updateCurrentPageDisplay; // update page display to match the currentPage. ignored if defersCurrentPageDisplay is NO. setting the page value directly will update immediately
- (CGRect)rectForPageIndicator:(NSInteger)pageIndex;
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount;
- (void)setImage:(UIImage *)image forPage:(NSInteger)pageIndex;
- (void)setCurrentImage:(UIImage *)image forPage:(NSInteger)pageIndex;
- (void)setImageMask:(UIImage *)image forPage:(NSInteger)pageIndex;
- (UIImage *)imageForPage:(NSInteger)pageIndex;
- (UIImage *)currentImageForPage:(NSInteger)pageIndex;
- (UIImage *)imageMaskForPage:(NSInteger)pageIndex;
- (void)updatePageNumberForScrollView:(UIScrollView *)scrollView;
- (void)setScrollViewContentOffsetForCurrentPage:(UIScrollView *)scrollView animated:(BOOL)animated;
#pragma mark - UIAccessibility
// SMPageControl mirrors UIPageControl's standard accessibility functionality by default.
// Basically, the accessibility label is set to "[current page index + 1] of [page count]".
// SMPageControl extends UIPageControl's functionality by allowing you to name specific pages. This is especially useful when using
// the per-page indicator images, and allows you to provide more context to the user.
- (void)setName:(NSString *)name forPage:(NSInteger)pageIndex;
- (NSString *)nameForPage:(NSInteger)pageIndex;
@end
... ...
//
// SMPageControl.m
// SMPageControl
//
// Created by Jerry Jones on 10/13/12.
// Copyright (c) 2012 Spaceman Labs. All rights reserved.
//
#import "SMPageControl.h"
#if ! __has_feature(objc_arc)
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
#endif
#define DEFAULT_INDICATOR_WIDTH 6.0f
#define DEFAULT_INDICATOR_MARGIN 10.0f
#define DEFAULT_MIN_HEIGHT 36.0f
#define DEFAULT_INDICATOR_WIDTH_LARGE 7.0f
#define DEFAULT_INDICATOR_MARGIN_LARGE 9.0f
#define DEFAULT_MIN_HEIGHT_LARGE 36.0f
typedef NS_ENUM(NSUInteger, SMPageControlImageType) {
SMPageControlImageTypeNormal = 1,
SMPageControlImageTypeCurrent,
SMPageControlImageTypeMask
};
typedef NS_ENUM(NSUInteger, SMPageControlStyleDefaults) {
SMPageControlDefaultStyleClassic = 0,
SMPageControlDefaultStyleModern
};
static SMPageControlStyleDefaults _defaultStyleForSystemVersion;
@interface SMPageControl ()
@property (strong, readonly, nonatomic) NSMutableDictionary *pageNames;
@property (strong, readonly, nonatomic) NSMutableDictionary *pageImages;
@property (strong, readonly, nonatomic) NSMutableDictionary *currentPageImages;
@property (strong, readonly, nonatomic) NSMutableDictionary *pageImageMasks;
@property (strong, readonly, nonatomic) NSMutableDictionary *cgImageMasks;
@property (strong, readwrite, nonatomic) NSArray *pageRects;
// Page Control used for stealing page number localizations for accessibility labels
// I'm not sure I love this technique, but it's the best way to get exact translations for all the languages
// that Apple supports out of the box
@property (nonatomic, strong) UIPageControl *accessibilityPageControl;
@end
@implementation SMPageControl
{
@private
NSInteger _displayedPage;
CGFloat _measuredIndicatorWidth;
CGFloat _measuredIndicatorHeight;
CGImageRef _pageImageMask;
}
@synthesize pageNames = _pageNames;
@synthesize pageImages = _pageImages;
@synthesize currentPageImages = _currentPageImages;
@synthesize pageImageMasks = _pageImageMasks;
@synthesize cgImageMasks = _cgImageMasks;
+ (void)initialize
{
NSString *reqSysVer = @"7.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
_defaultStyleForSystemVersion = SMPageControlDefaultStyleModern;
} else {
_defaultStyleForSystemVersion = SMPageControlDefaultStyleClassic;
}
}
- (void)_initialize
{
_numberOfPages = 0;
_tapBehavior = SMPageControlTapBehaviorStep;
self.backgroundColor = [UIColor clearColor];
// If the app wasn't linked against iOS 7 or newer, always use the classic style
// otherwise, use the style of the current OS.
#ifdef __IPHONE_7_0
[self setStyleWithDefaults:_defaultStyleForSystemVersion];
#else
[self setStyleWithDefaults:SMPageControlDefaultStyleClassic];
#endif
_alignment = SMPageControlAlignmentCenter;
_verticalAlignment = SMPageControlVerticalAlignmentMiddle;
self.isAccessibilityElement = YES;
self.accessibilityTraits = UIAccessibilityTraitUpdatesFrequently;
self.accessibilityPageControl = [[UIPageControl alloc] init];
self.contentMode = UIViewContentModeRedraw;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (nil == self) {
return nil;
}
[self _initialize];
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (nil == self) {
return nil;
}
[self _initialize];
return self;
}
- (void)dealloc
{
if (_pageImageMask) {
CGImageRelease(_pageImageMask);
}
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
[self _renderPages:context rect:rect];
}
- (void)_renderPages:(CGContextRef)context rect:(CGRect)rect
{
NSMutableArray *pageRects = [NSMutableArray arrayWithCapacity:self.numberOfPages];
if (_numberOfPages < 2 && _hidesForSinglePage) {
return;
}
CGFloat left = [self _leftOffset];
CGFloat xOffset = left;
CGFloat yOffset = 0.0f;
UIColor *fillColor = nil;
UIImage *image = nil;
CGImageRef maskingImage = nil;
CGSize maskSize = CGSizeZero;
for (NSInteger i = 0; i < _numberOfPages; i++) {
NSNumber *indexNumber = @(i);
if (i == _displayedPage) {
fillColor = _currentPageIndicatorTintColor ? _currentPageIndicatorTintColor : [UIColor whiteColor];
image = _currentPageImages[indexNumber];
if (nil == image) {
image = _currentPageIndicatorImage;
}
} else {
fillColor = _pageIndicatorTintColor ? _pageIndicatorTintColor : [[UIColor whiteColor] colorWithAlphaComponent:0.3f];
image = _pageImages[indexNumber];
if (nil == image) {
image = _pageIndicatorImage;
}
}
// If no finished images have been set, try a masking image
if (nil == image) {
maskingImage = (__bridge CGImageRef)_cgImageMasks[indexNumber];
UIImage *originalImage = _pageImageMasks[indexNumber];
maskSize = originalImage.size;
// If no per page mask is set, try for a global page mask!
if (nil == maskingImage) {
maskingImage = _pageImageMask;
maskSize = _pageIndicatorMaskImage.size;
}
}
[fillColor set];
CGRect indicatorRect;
if (image) {
yOffset = [self _topOffsetForHeight:image.size.height rect:rect];
CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - image.size.width) / 2.0f);
[image drawAtPoint:CGPointMake(centeredXOffset, yOffset)];
indicatorRect = CGRectMake(centeredXOffset, yOffset, image.size.width, image.size.height);
} else if (maskingImage) {
yOffset = [self _topOffsetForHeight:maskSize.height rect:rect];
CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - maskSize.width) / 2.0f);
indicatorRect = CGRectMake(centeredXOffset, yOffset, maskSize.width, maskSize.height);
CGContextDrawImage(context, indicatorRect, maskingImage);
} else {
yOffset = [self _topOffsetForHeight:_indicatorDiameter rect:rect];
CGFloat centeredXOffset = xOffset + floorf((_measuredIndicatorWidth - _indicatorDiameter) / 2.0f);
indicatorRect = CGRectMake(centeredXOffset, yOffset, _indicatorDiameter, _indicatorDiameter);
CGContextFillEllipseInRect(context, indicatorRect);
}
[pageRects addObject:[NSValue valueWithCGRect:indicatorRect]];
maskingImage = NULL;
xOffset += _measuredIndicatorWidth + _indicatorMargin;
}
self.pageRects = pageRects;
}
- (CGFloat)_leftOffset
{
CGRect rect = self.bounds;
CGSize size = [self sizeForNumberOfPages:self.numberOfPages];
CGFloat left = 0.0f;
switch (_alignment) {
case SMPageControlAlignmentCenter:
left = ceilf(CGRectGetMidX(rect) - (size.width / 2.0f));
break;
case SMPageControlAlignmentRight:
left = CGRectGetMaxX(rect) - size.width;
break;
default:
break;
}
return left;
}
- (CGFloat)_topOffsetForHeight:(CGFloat)height rect:(CGRect)rect
{
CGFloat top = 0.0f;
switch (_verticalAlignment) {
case SMPageControlVerticalAlignmentMiddle:
top = CGRectGetMidY(rect) - (height / 2.0f);
break;
case SMPageControlVerticalAlignmentBottom:
top = CGRectGetMaxY(rect) - height;
break;
default:
break;
}
return top;
}
- (void)updateCurrentPageDisplay
{
_displayedPage = _currentPage;
[self setNeedsDisplay];
}
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount
{
CGFloat marginSpace = MAX(0, pageCount - 1) * _indicatorMargin;
CGFloat indicatorSpace = pageCount * _measuredIndicatorWidth;
CGSize size = CGSizeMake(marginSpace + indicatorSpace, _measuredIndicatorHeight);
return size;
}
- (CGRect)rectForPageIndicator:(NSInteger)pageIndex
{
if (pageIndex < 0 || pageIndex >= _numberOfPages) {
return CGRectZero;
}
CGFloat left = [self _leftOffset];
CGSize size = [self sizeForNumberOfPages:pageIndex + 1];
CGRect rect = CGRectMake(left + size.width - _measuredIndicatorWidth, 0, _measuredIndicatorWidth, _measuredIndicatorWidth);
return rect;
}
- (void)_setImage:(UIImage *)image forPage:(NSInteger)pageIndex type:(SMPageControlImageType)type
{
if (pageIndex < 0 || pageIndex >= _numberOfPages) {
return;
}
NSMutableDictionary *dictionary = nil;
switch (type) {
case SMPageControlImageTypeCurrent:
dictionary = self.currentPageImages;
break;
case SMPageControlImageTypeNormal:
dictionary = self.pageImages;
break;
case SMPageControlImageTypeMask:
dictionary = self.pageImageMasks;
break;
default:
break;
}
if (image) {
dictionary[@(pageIndex)] = image;
} else {
[dictionary removeObjectForKey:@(pageIndex)];
}
}
- (void)setImage:(UIImage *)image forPage:(NSInteger)pageIndex
{
[self _setImage:image forPage:pageIndex type:SMPageControlImageTypeNormal];
[self _updateMeasuredIndicatorSizes];
}
- (void)setCurrentImage:(UIImage *)image forPage:(NSInteger)pageIndex
{
[self _setImage:image forPage:pageIndex type:SMPageControlImageTypeCurrent];;
[self _updateMeasuredIndicatorSizes];
}
- (void)setImageMask:(UIImage *)image forPage:(NSInteger)pageIndex
{
[self _setImage:image forPage:pageIndex type:SMPageControlImageTypeMask];
if (nil == image) {
[self.cgImageMasks removeObjectForKey:@(pageIndex)];
return;
}
CGImageRef maskImage = [self createMaskForImage:image];
if (maskImage) {
self.cgImageMasks[@(pageIndex)] = (__bridge id)maskImage;
CGImageRelease(maskImage);
[self _updateMeasuredIndicatorSizeWithSize:image.size];
[self setNeedsDisplay];
}
}
- (id)_imageForPage:(NSInteger)pageIndex type:(SMPageControlImageType)type
{
if (pageIndex < 0 || pageIndex >= _numberOfPages) {
return nil;
}
NSDictionary *dictionary = nil;
switch (type) {
case SMPageControlImageTypeCurrent:
dictionary = _currentPageImages;
break;
case SMPageControlImageTypeNormal:
dictionary = _pageImages;
break;
case SMPageControlImageTypeMask:
dictionary = _pageImageMasks;
break;
default:
break;
}
return dictionary[@(pageIndex)];
}
- (UIImage *)imageForPage:(NSInteger)pageIndex
{
return [self _imageForPage:pageIndex type:SMPageControlImageTypeNormal];
}
- (UIImage *)currentImageForPage:(NSInteger)pageIndex
{
return [self _imageForPage:pageIndex type:SMPageControlImageTypeCurrent];
}
- (UIImage *)imageMaskForPage:(NSInteger)pageIndex
{
return [self _imageForPage:pageIndex type:SMPageControlImageTypeMask];
}
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize sizeThatFits = [self sizeForNumberOfPages:self.numberOfPages];
sizeThatFits.height = MAX(sizeThatFits.height, _minHeight);
return sizeThatFits;
}
- (CGSize)intrinsicContentSize
{
if (_numberOfPages < 1 || (_numberOfPages < 2 && _hidesForSinglePage)) {
return CGSizeMake(UIViewNoIntrinsicMetric, 0.0f);
}
CGSize intrinsicContentSize = CGSizeMake(UIViewNoIntrinsicMetric, MAX(_measuredIndicatorHeight, _minHeight));
return intrinsicContentSize;
}
- (void)updatePageNumberForScrollView:(UIScrollView *)scrollView
{
NSInteger page = (int)floorf(scrollView.contentOffset.x / scrollView.bounds.size.width);
self.currentPage = page;
}
- (void)setScrollViewContentOffsetForCurrentPage:(UIScrollView *)scrollView animated:(BOOL)animated
{
CGPoint offset = scrollView.contentOffset;
offset.x = scrollView.bounds.size.width * self.currentPage;
[scrollView setContentOffset:offset animated:animated];
}
- (void)setStyleWithDefaults:(SMPageControlStyleDefaults)defaultStyle
{
switch (defaultStyle) {
case SMPageControlDefaultStyleModern:
self.indicatorDiameter = DEFAULT_INDICATOR_WIDTH_LARGE;
self.indicatorMargin = DEFAULT_INDICATOR_MARGIN_LARGE;
self.pageIndicatorTintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.2f];
self.minHeight = DEFAULT_MIN_HEIGHT_LARGE;
break;
case SMPageControlDefaultStyleClassic:
default:
self.indicatorDiameter = DEFAULT_INDICATOR_WIDTH;
self.indicatorMargin = DEFAULT_INDICATOR_MARGIN;
self.pageIndicatorTintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.3f];
self.minHeight = DEFAULT_MIN_HEIGHT;
break;
}
}
#pragma mark -
- (CGImageRef)createMaskForImage:(UIImage *)image CF_RETURNS_RETAINED
{
size_t pixelsWide = image.size.width * image.scale;
size_t pixelsHigh = image.size.height * image.scale;
size_t bitmapBytesPerRow = (pixelsWide * 1);
CGContextRef context = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh, CGImageGetBitsPerComponent(image.CGImage), bitmapBytesPerRow, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
CGContextTranslateCTM(context, 0.f, pixelsHigh);
CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextDrawImage(context, CGRectMake(0, 0, pixelsWide, pixelsHigh), image.CGImage);
CGImageRef maskImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return maskImage;
}
- (void)_updateMeasuredIndicatorSizeWithSize:(CGSize)size
{
_measuredIndicatorWidth = MAX(_measuredIndicatorWidth, size.width);
_measuredIndicatorHeight = MAX(_measuredIndicatorHeight, size.height);
}
- (void)_updateMeasuredIndicatorSizes
{
_measuredIndicatorWidth = _indicatorDiameter;
_measuredIndicatorHeight = _indicatorDiameter;
// If we're only using images, ignore the _indicatorDiameter
if ( (self.pageIndicatorImage || self.pageIndicatorMaskImage) && self.currentPageIndicatorImage )
{
_measuredIndicatorWidth = 0;
_measuredIndicatorHeight = 0;
}
if (self.pageIndicatorImage) {
[self _updateMeasuredIndicatorSizeWithSize:self.pageIndicatorImage.size];
}
if (self.currentPageIndicatorImage) {
[self _updateMeasuredIndicatorSizeWithSize:self.currentPageIndicatorImage.size];
}
if (self.pageIndicatorMaskImage) {
[self _updateMeasuredIndicatorSizeWithSize:self.pageIndicatorMaskImage.size];
}
if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {
[self invalidateIntrinsicContentSize];
}
}
#pragma mark - Tap Gesture
// We're using touchesEnded: because we want to mimick UIPageControl as close as possible
// As of iOS 6, UIPageControl still (as far as we know) does not use a tap gesture recognizer. This means that actions like
// touching down, sliding around, and releasing, still results in the page incrementing or decrementing.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
if (SMPageControlTapBehaviorJump == self.tapBehavior) {
__block NSInteger tappedIndicatorIndex = NSNotFound;
[self.pageRects enumerateObjectsUsingBlock:^(NSValue *value, NSUInteger index, BOOL *stop) {
CGRect indicatorRect = [value CGRectValue];
if (CGRectContainsPoint(indicatorRect, point)) {
tappedIndicatorIndex = index;
*stop = YES;
}
}];
if (NSNotFound != tappedIndicatorIndex) {
[self setCurrentPage:tappedIndicatorIndex sendEvent:YES canDefer:YES];
return;
}
}
CGSize size = [self sizeForNumberOfPages:self.numberOfPages];
CGFloat left = [self _leftOffset];
CGFloat middle = left + (size.width / 2.0f);
if (point.x < middle) {
[self setCurrentPage:self.currentPage - 1 sendEvent:YES canDefer:YES];
} else {
[self setCurrentPage:self.currentPage + 1 sendEvent:YES canDefer:YES];
}
}
#pragma mark - Accessors
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self setNeedsDisplay];
}
- (void)setIndicatorDiameter:(CGFloat)indicatorDiameter
{
if (indicatorDiameter == _indicatorDiameter) {
return;
}
_indicatorDiameter = indicatorDiameter;
// Absolute minimum height of the control is the indicator diameter
if (_minHeight < indicatorDiameter) {
self.minHeight = indicatorDiameter;
}
[self _updateMeasuredIndicatorSizes];
[self setNeedsDisplay];
}
- (void)setIndicatorMargin:(CGFloat)indicatorMargin
{
if (indicatorMargin == _indicatorMargin) {
return;
}
_indicatorMargin = indicatorMargin;
[self setNeedsDisplay];
}
- (void)setMinHeight:(CGFloat)minHeight
{
if (minHeight == _minHeight) {
return;
}
// Absolute minimum height of the control is the indicator diameter
if (minHeight < _indicatorDiameter) {
minHeight = _indicatorDiameter;
}
_minHeight = minHeight;
if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {
[self invalidateIntrinsicContentSize];
}
[self setNeedsLayout];
}
- (void)setNumberOfPages:(NSInteger)numberOfPages
{
[self setHidden:(numberOfPages<=1)];
if (numberOfPages == _numberOfPages) {
return;
}
self.accessibilityPageControl.numberOfPages = numberOfPages;
_numberOfPages = MAX(0, numberOfPages);
if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {
[self invalidateIntrinsicContentSize];
}
[self updateAccessibilityValue];
[self setNeedsDisplay];
}
- (void)setCurrentPage:(NSInteger)currentPage
{
[self setCurrentPage:currentPage sendEvent:NO canDefer:NO];
}
- (void)setCurrentPage:(NSInteger)currentPage sendEvent:(BOOL)sendEvent canDefer:(BOOL)defer
{
_currentPage = MIN(MAX(0, currentPage), _numberOfPages - 1);
self.accessibilityPageControl.currentPage = self.currentPage;
[self updateAccessibilityValue];
if (NO == self.defersCurrentPageDisplay || NO == defer) {
_displayedPage = _currentPage;
[self setNeedsDisplay];
}
if (sendEvent) {
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
- (void)setCurrentPageIndicatorImage:(UIImage *)currentPageIndicatorImage
{
if ([currentPageIndicatorImage isEqual:_currentPageIndicatorImage]) {
return;
}
_currentPageIndicatorImage = currentPageIndicatorImage;
[self _updateMeasuredIndicatorSizes];
[self setNeedsDisplay];
}
- (void)setPageIndicatorImage:(UIImage *)pageIndicatorImage
{
if ([pageIndicatorImage isEqual:_pageIndicatorImage]) {
return;
}
_pageIndicatorImage = pageIndicatorImage;
[self _updateMeasuredIndicatorSizes];
[self setNeedsDisplay];
}
- (void)setPageIndicatorMaskImage:(UIImage *)pageIndicatorMaskImage
{
if ([pageIndicatorMaskImage isEqual:_pageIndicatorMaskImage]) {
return;
}
_pageIndicatorMaskImage = pageIndicatorMaskImage;
if (_pageImageMask) {
CGImageRelease(_pageImageMask);
}
_pageImageMask = [self createMaskForImage:_pageIndicatorMaskImage];
[self _updateMeasuredIndicatorSizes];
[self setNeedsDisplay];
}
- (NSMutableDictionary *)pageNames
{
if (nil != _pageNames) {
return _pageNames;
}
_pageNames = [[NSMutableDictionary alloc] init];
return _pageNames;
}
- (NSMutableDictionary *)pageImages
{
if (nil != _pageImages) {
return _pageImages;
}
_pageImages = [[NSMutableDictionary alloc] init];
return _pageImages;
}
- (NSMutableDictionary *)currentPageImages
{
if (nil != _currentPageImages) {
return _currentPageImages;
}
_currentPageImages = [[NSMutableDictionary alloc] init];
return _currentPageImages;
}
- (NSMutableDictionary *)pageImageMasks
{
if (nil != _pageImageMasks) {
return _pageImageMasks;
}
_pageImageMasks = [[NSMutableDictionary alloc] init];
return _pageImageMasks;
}
- (NSMutableDictionary *)cgImageMasks
{
if (nil != _cgImageMasks) {
return _cgImageMasks;
}
_cgImageMasks = [[NSMutableDictionary alloc] init];
return _cgImageMasks;
}
#pragma mark - UIAccessibility
- (void)setName:(NSString *)name forPage:(NSInteger)pageIndex
{
if (pageIndex < 0 || pageIndex >= _numberOfPages) {
return;
}
self.pageNames[@(pageIndex)] = name;
}
- (NSString *)nameForPage:(NSInteger)pageIndex
{
if (pageIndex < 0 || pageIndex >= _numberOfPages) {
return nil;
}
return self.pageNames[@(pageIndex)];
}
- (void)updateAccessibilityValue
{
NSString *pageName = [self nameForPage:self.currentPage];
NSString *accessibilityValue = self.accessibilityPageControl.accessibilityValue;
if (pageName) {
self.accessibilityValue = [NSString stringWithFormat:@"%@ - %@", pageName, accessibilityValue];
} else {
self.accessibilityValue = accessibilityValue;
}
}
@end
... ...
... ... @@ -44,6 +44,7 @@
#define IS_IPHONE_5_OR_MORE (IS_IPHONE && SCREEN_MAX_LENGTH >= 568.0)
//部分屏幕尺寸基于320等比例放大的尺寸
#define kScreenPointScale CGRectGetWidth([[UIScreen mainScreen] bounds])/320.0f
#define kScreenPoint6Scale CGRectGetWidth([[UIScreen mainScreen] bounds])/375.0f
#define BLOCK_EXEC(block, ...) if (block) { block(__VA_ARGS__); };
... ... @@ -54,6 +55,12 @@
#define kUserInterfaceIdiomIsPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define kScreenWidth ([[UIScreen mainScreen] bounds].size.width)
#define kScreenHeight ([[UIScreen mainScreen] bounds].size.height)
#define Screen35in (kScreenHeight==480)
#define Screen40in (kScreenHeight==568)
#define Screen47in (kScreenHeight==667)
#define Screen55in (kScreenHeight==736)
// 获取RGB颜色
#define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
#define RGB(r,g,b) RGBA(r,g,b,1.0f)
... ...
//
// YH_GuideViewController.h
// YH_Mall
//
// Created by YOHO on 15/4/30.
// Copyright (c) 2015年 YOHO. All rights reserved.
//
typedef void (^ClickBlock)();
@interface YH_GuideViewController : UIViewController
@property (readwrite, nonatomic, copy) ClickBlock block;
@end
... ...
//
// YH_GuideViewController.m
// YH_Mall
//
// Created by YOHO on 15/4/30.
// Copyright (c) 2015年 YOHO. All rights reserved.
//
#import "YH_GuideViewController.h"
#import "SMPageControl.h"
#define kNumberOfImages 4
@interface YH_GuideViewController ()<UIScrollViewDelegate>
@property (strong ,nonatomic) UIScrollView *scrollView;
@property (strong ,nonatomic) SMPageControl *pageControl;
@property (assign ,nonatomic) NSInteger currentPage;
@property (strong ,nonatomic) UIButton *enterButton;
@end
@implementation YH_GuideViewController
- (instancetype)init
{
self = [super init];
if(self){
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.enterButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.enterButton.backgroundColor = [UIColor clearColor];
[self.enterButton addTarget:self action:@selector(didClickEnterButton:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.view addSubview:self.scrollView];
[self.view insertSubview:self.pageControl aboveSubview:self.scrollView];
}
- (UIScrollView *)scrollView
{
if(!_scrollView){
_scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[_scrollView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
_scrollView.contentSize = CGSizeMake(kScreenWidth * kNumberOfImages, CGRectGetHeight(self.view.frame));
_scrollView.pagingEnabled = YES;
_scrollView.delegate = self;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.bounces = NO;
for (int i = 0; i < kNumberOfImages; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(i * kScreenWidth , 0, kScreenWidth, kScreenHeight)];
NSString *imageName = [NSString stringWithFormat:@"guide_%d.png",(i + 1)];
imageView.image = [UIImage imageNamed:imageName];
if(i == kNumberOfImages - 1){
imageView.userInteractionEnabled = YES;
CGSize size = CGSizeMake(124*kScreenPoint6Scale, 45*kScreenPoint6Scale);
if(Screen35in){
self.enterButton.frame = CGRectMake((kScreenWidth - size.width) / 2.0f, 386, size.width, size.height);
} else{
self.enterButton.frame = CGRectMake((kScreenWidth - size.width) / 2.0f, 538*kScreenPoint6Scale, size.width, size.height);
}
[imageView addSubview:self.enterButton];
}
[self.scrollView addSubview:imageView];
}
}
return _scrollView;
}
- (SMPageControl *)pageControl
{
if(!_pageControl){
_pageControl = [[SMPageControl alloc] init];
_pageControl.indicatorMargin = 18.0f;
_pageControl.numberOfPages = kNumberOfImages;
_pageControl.userInteractionEnabled = NO;
[_pageControl sizeToFit];
_pageControl.center = self.enterButton.center;
CGRect frame = _pageControl.frame;
if(Screen35in){
frame.origin.y += 0.8 * CGRectGetHeight(self.enterButton.frame);
} else if(Screen40in){
frame.origin.y += CGRectGetHeight(self.enterButton.frame);
} else{
frame.origin.y += 1.3 * CGRectGetHeight(self.enterButton.frame);
}
_pageControl.frame = frame;
}
return _pageControl;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger page = scrollView.contentOffset.x / kScreenWidth;
if(page != self.currentPage){
self.currentPage = page;
}
self.pageControl.currentPage = self.currentPage;
}
- (void)didClickEnterButton:(UIButton *)button
{
if(self.block){
self.block();
}
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
@end
... ...