Commit 69937f63 authored by 翟国钧's avatar 翟国钧

增加device_id

parent 09e29837
PODS:
- Base64nl (1.2)
- GMCache (0.1.0):
- TMCache (~> 2.1.0)
- GMPhobos (0.2.17):
- GMFoundation (0.0.2):
- Base64nl (= 1.2)
- GMKit (0.7.11):
- GMFoundation
- GMOCConstant
- Masonry (= 1.0.1)
- SDWebImage (= 3.7.6)
- GMOCConstant (0.0.3)
- GMPhobos (0.2.18):
- GMCache (~> 0.1.0)
- GMKit
- Masonry (1.0.1)
- SDWebImage (3.7.6):
- SDWebImage/Core (= 3.7.6)
- SDWebImage/Core (3.7.6)
- TMCache (2.1.0)
DEPENDENCIES:
......@@ -13,10 +27,16 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
Base64nl: a497bdcd1c01ea793d36b399016195a8713c0e95
GMCache: a7b06a2d8a5a1c7cf023055c631ba9a0cd7c39fc
GMPhobos: cc235c25ee41af5adaae4cdc140a6d80294c98c9
GMFoundation: 08b2e6e12c211ed37aa5dce3588f645a133b9165
GMKit: 04a30d67c6b5468f07c8d9f60d0f8b12dd90b162
GMOCConstant: 39371248b4d8d54929391bfcd2c5883776436c4b
GMPhobos: 4549142bc1d9ffdae74b4fd44e3a102ac718d62a
Masonry: a1a931a0d08870ed8ae415a2ea5ea68ebcac77df
SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
PODFILE CHECKSUM: ab2b5ff1dcd8a35fd02cced6c06c7f9477b82d69
COCOAPODS: 1.1.0.rc.2
COCOAPODS: 1.1.1
//
// Base64.h
//
// Version 1.2
//
// Created by Nick Lockwood on 12/01/2012.
// Copyright (C) 2012 Charcoal Design
//
// Distributed under the permissive zlib License
// Get the latest version from here:
//
// https://github.com/nicklockwood/Base64
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
#import <Foundation/Foundation.h>
@interface NSData (Base64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
- (NSString *)base64EncodedString;
@end
@interface NSString (Base64)
+ (NSString *)stringWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
- (NSString *)base64EncodedString;
- (NSString *)base64DecodedString;
- (NSData *)base64DecodedData;
@end
//
// Base64.m
//
// Version 1.2
//
// Created by Nick Lockwood on 12/01/2012.
// Copyright (C) 2012 Charcoal Design
//
// Distributed under the permissive zlib License
// Get the latest version from here:
//
// https://github.com/nicklockwood/Base64
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an aacknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
#import "Base64.h"
#pragma GCC diagnostic ignored "-Wselector"
#import <Availability.h>
#if !__has_feature(objc_arc)
#error This library requires automatic reference counting
#endif
@implementation NSData (Base64)
+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
if (![string length]) return nil;
NSData *decoded = nil;
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
if (![NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)])
{
decoded = [[self alloc] initWithBase64Encoding:[string stringByReplacingOccurrencesOfString:@"[^A-Za-z0-9+/=]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [string length])]];
}
else
#endif
{
decoded = [[self alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters];
}
return [decoded length]? decoded: nil;
}
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
{
if (![self length]) return nil;
NSString *encoded = nil;
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
if (![NSData instancesRespondToSelector:@selector(base64EncodedStringWithOptions:)])
{
encoded = [self base64Encoding];
}
else
#endif
{
switch (wrapWidth)
{
case 64:
{
return [self base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
case 76:
{
return [self base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
}
default:
{
encoded = [self base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];
}
}
}
if (!wrapWidth || wrapWidth >= [encoded length])
{
return encoded;
}
wrapWidth = (wrapWidth / 4) * 4;
NSMutableString *result = [NSMutableString string];
for (NSUInteger i = 0; i < [encoded length]; i+= wrapWidth)
{
if (i + wrapWidth >= [encoded length])
{
[result appendString:[encoded substringFromIndex:i]];
break;
}
[result appendString:[encoded substringWithRange:NSMakeRange(i, wrapWidth)]];
[result appendString:@"\r\n"];
}
return result;
}
- (NSString *)base64EncodedString
{
return [self base64EncodedStringWithWrapWidth:0];
}
@end
@implementation NSString (Base64)
+ (NSString *)stringWithBase64EncodedString:(NSString *)string
{
NSData *data = [NSData dataWithBase64EncodedString:string];
if (data)
{
return [[self alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
return nil;
}
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
{
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
return [data base64EncodedStringWithWrapWidth:wrapWidth];
}
- (NSString *)base64EncodedString
{
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
return [data base64EncodedString];
}
- (NSString *)base64DecodedString
{
return [NSString stringWithBase64EncodedString:self];
}
- (NSData *)base64DecodedData
{
return [NSData dataWithBase64EncodedString:self];
}
@end
Base64
Version 1.2, Feburary 7th, 2014
Copyright (C) 2012 Charcoal Design
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
\ No newline at end of file
NOTE: As of iOS 7 and Mac OS 10.9, this library is not longer needed
----------------------------------------------------------------------
In the iOS 7 and Mac OS 10.9 SDKs, Apple introduced new base64 methods on NSData that make it unnecessary to use a 3rd party base 64 decoding library. What's more, they exposed access to private base64 methods that are retrospectively available back as far as IOS 4 and Mac OS 6.
Although use of this library is no longer required, you may still find it useful, as it abstracts the complexity of supporting the deprecated Base64 methods for older OS versions, and also provides some additional utility functions, such as arbitrary wrap widths and NSString encoding.
Purpose
--------------
Base64 is a set of categories that provide methods to encode and decode data as a base-64-encoded string.
Supported OS & SDK Versions
-----------------------------
* Supported build target - iOS 7.0 / Mac OS 10.9 (Xcode 5.0, Apple LLVM compiler 5.0)
* Earliest supported deployment target - iOS 5.0 / Mac OS 10.7
* Earliest compatible deployment target - iOS 4.3 / Mac OS 10.6
NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this iOS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.
ARC Compatibility
------------------
As of version 1.1, Base64 requires ARC. If you wish to use Base64 in a non-ARC project, just add the -fobjc-arc compiler flag to the Base64.m file. To do this, go to the Build Phases tab in your target settings, open the Compile Sources group, double-click Base64.m in the list and type -fobjc-arc into the popover.
If you wish to convert your whole project to ARC, comment out the #error line in Base64.m, then run the Edit > Refactor > Convert to Objective-C ARC... tool in Xcode and make sure all files that you wish to use ARC for (including Base64.m) are checked.
Thread Safety
--------------
All the Base64 methods should be safe to call from multiple threads concurrently.
Installation
--------------
To use the Base64 category in an app, just drag the category files (demo files and assets are not needed) into your project and import the header file into any class where you wish to make use of the Base64 functionality.
NSData Extensions
----------------------
Base64 extends NSData with the following methods:
+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
Takes a base-64-encoded string and returns an autoreleased NSData object containing the decoded data. Any non-base-64 characters in the string are ignored, so it is safe to pass a string containing line breaks or other delimiters.
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
Encodes the data as a base-64-encoded string and returns it. The wrapWidth argument allows you to specify the number of characters at which the output should wrap onto a new line. The value of wrapWidth must be a multiple of four. Values that are not a multiple of four will be truncated to the nearest multiple. A value of zero indicates that the data should not wrap.
- (NSString *)base64EncodedString;
Encodes the data as a base-64-encoded string without any wrapping (line breaks).
NSString Extensions
----------------------
Base64 extends NSString with the following methods:
+ (NSString *)stringWithBase64EncodedString:(NSString *)string;
Takes a base-64-encoded string and returns an autoreleased NSString object containing the decoded data, interpreted using UTF8 encoding. The vast majority of use cases for Base64 encoding use Ascii or UTF8 strings, so this should be sufficient for most purposes. If you do need to decode string data in an encoding other than UTF8, convert your string to an NSData object first and then use the NSData dataWithBase64EncodedString: method instead.
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
Converts the string data to UTF8 data and then encodes the data as a base-64-encoded string and returns it. The wrapWidth argument allows you to specify the number of characters at which the output should wrap onto a new line. The value of wrapWidth must be a multiple of four. Values that are not a multiple of four will be truncated to the nearest multiple. A value of zero indicates that the data should not wrap.
- (NSString *)base64EncodedString;
Encodes the string as UTF8 data and then encodes that as a base-64-encoded string without any wrapping (line breaks).
- (NSString *)base64DecodedString;
Treats the string as a base-64-encoded string and returns an autoreleased NSString object containing the decoded data, interpreted using UTF8 encoding. Any non-base-64 characters in the string are ignored, so it is safe to use a string containing line breaks or other delimiters.
- (NSData *)base64DecodedData;
Treats the string as base-64-encoded data and returns an autoreleased NSData object containing the decoded data. Any non-base-64 characters in the string are ignored, so it is safe to use a string containing line breaks or other delimiters.
\ No newline at end of file
//
// GMFont.h
// Gengmei
//
// Created by Thierry on 2/9/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
#define GMFont(size) [UIFont gm_fontWithSize:size]
@interface UIFont (GMFont)
+ (UIFont *)gm_fontWithSize:(NSInteger)size;
@end
//
// GMFont.m
// Gengmei
//
// Created by Thierry on 2/9/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMFont.h"
/*
更美-方正兰亭黑 familyName: GMEI_FZLTH_Thin_GB_YS
familyName 下只有一个字体: FZLTHThin--GB1-4-YS
可以用如下方式取得某个 familyName 下的所有字体
for (NSString *name in [UIFont fontNamesForFamilyName:@"GMEI_FZLTH_Thin_GB_YS"]) {
NSLog(@"%@", name);
}
*/
@implementation UIFont (GMFont)
+ (UIFont *)gm_fontWithSize:(NSInteger)size {
UIFont *font = [UIFont fontWithName:@"FZLTHThin--GB1-4-YS" size:size];
if (!font) {
if(([[[UIDevice currentDevice] systemVersion] compare:@"9.0" options:NSNumericSearch] != NSOrderedAscending)) {
return [UIFont fontWithName:@"PingFangSC-Regular" size:size];
}else{
return [UIFont fontWithName:@"STHeitiSC-Light" size:size];
}
}
return font;
}
@end
//
// NSAttributedString+GMSize.h
// Gengmei
//
// Created by wangyang on 7/22/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSAttributedString (GMSize)
+ (NSMutableAttributedString *)string:(NSString *)string font:(UIFont *)font color:(UIColor *)color shadow:(BOOL)needShadow;
+ (NSMutableAttributedString *)attributedStringWithString:(NSString *)string fontSize:(CGFloat)size textColor:(UIColor *)color;
/**
* @brief 适用于为整个 string 添加属性,其中的 paragraphStyle 为 mutable 的,可以取出来再次修改
@note 最佳使用方法: 用该方法创建 attributedString,再使用 sizeForBoundingRectSize: 方法来计算大小.
@note 默认为 TruncatingTail
*/
+ (NSMutableAttributedString *)attributedStringWithString:(NSString *)string trimBothEndSpace:(BOOL)tripSpace trimInnerReturnSpace:(BOOL)trimReturn fontSize:(CGFloat)size textColor:(UIColor *)color lineSpacing:(CGFloat)spacing;
/**
* @brief 使用该方法返回 attributedString 的大小。比如指定{320, 99},那么就会返回一个不超过该大小的 size,且宽高都经过 ceilf 处理
*
* @param maxSize 指定的最大的 string 大小。
*
* @return 经过 ceilf 处理的最大 size
*/
- (CGSize)sizeForBoundingRectSize:(CGSize)maxSize;
@end
@interface NSMutableAttributedString (GM)
- (void)addJustifiedAligment;
@end
@interface NSString (Attributed)
- (NSString *)trimInnerReturn;
- (NSString *)trimBothEnd;
- (NSMutableAttributedString *)fontSize:(NSInteger)size;
@end
@interface NSMutableAttributedString (Attributed)
- (NSMutableAttributedString *)addColor:(UIColor *)color;
- (NSMutableAttributedString *)addLineSpace:(NSInteger)space;
- (NSMutableAttributedString *)addShadow:(CGFloat)blur;
@end
\ No newline at end of file
//
// NSAttributedString+GMSize.m
// Gengmei
//
// Created by wangyang on 7/22/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "NSAttributedString+GMSize.h"
#import "GMFont.h"
#import "NSString+GM.h"
@implementation NSAttributedString (GMSize)
+ (NSMutableAttributedString *)string:(NSString *)string font:(UIFont *)font color:(UIColor *)color shadow:(BOOL)needShadow{
if (!font) {
NSAssert(0, @"请传递一个正常的字体参数");
}
if (!color) {
NSAssert(0, @"请传递一个正常的字体参数");
}
if (![string isNonEmpty]) {
return [[NSMutableAttributedString alloc] initWithString:@"" attributes:nil];;
}
NSMutableDictionary *stringAttribute = [@{NSForegroundColorAttributeName:color,
NSFontAttributeName:font} mutableCopy];
if (needShadow) {
NSShadow *shadow = [NSShadow new];
shadow.shadowOffset = CGSizeZero;
shadow.shadowBlurRadius = 5;
stringAttribute[NSShadowAttributeName] = shadow;
}
NSMutableAttributedString *attriString = [[NSMutableAttributedString alloc] initWithString:string attributes:stringAttribute];
return attriString;
}
+ (NSMutableAttributedString *)attributedStringWithString:(NSString *)string fontSize:(CGFloat)size textColor:(UIColor *)color{
return [self attributedStringWithString:string trimBothEndSpace:YES trimInnerReturnSpace:YES fontSize:size textColor:color lineSpacing:0];
}
+ (NSMutableAttributedString *)attributedStringWithString:(NSString *)string trimBothEndSpace:(BOOL)tripSpace trimInnerReturnSpace:(BOOL)trimReturn fontSize:(CGFloat)size textColor:(UIColor *)color lineSpacing:(CGFloat)spacing{
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = spacing;
style.lineBreakMode = NSLineBreakByTruncatingTail;
NSString *trimString = string;
if (tripSpace) {
trimString = [string trimSpace];
}
if (trimReturn) {
trimString = [trimString stringByReplacingOccurrencesOfString:@"\r" withString:@""];
trimString = [trimString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
}
if (!trimString) {
trimString = @"";
}
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:trimString attributes:@{NSFontAttributeName:GMFont(size), NSForegroundColorAttributeName:color, NSParagraphStyleAttributeName:style}];
return [attributedString mutableCopy];
}
- (CGSize)sizeForBoundingRectSize:(CGSize)maxSize{
// mutableCopy 以防修复原来的 string
NSMutableAttributedString *string = [self mutableCopy];
if (![string.string isNonEmpty]) {
return CGSizeZero;
}
// 修改 lineBreakMode 为 NSLineBreakByWordWrapping,因为 Truncate tail 会在 boundingRectWithSize 中指定,在这里指定了,反而会导致 boundingRectWithSize 方法计算不准确
NSMutableParagraphStyle *originStyle = [self attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL];
originStyle.lineBreakMode = NSLineBreakByWordWrapping;
CGSize size = [string boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine context:[[NSStringDrawingContext alloc] init]].size;
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
@end
@implementation NSMutableAttributedString (GM)
- (void)addJustifiedAligment {
if (self.length == 0) {
return;
}
NSRange range = NSMakeRange(0, self.length);
NSDictionary *dic = [self attributesAtIndex:0 effectiveRange:&range];
NSMutableParagraphStyle *style = dic[NSParagraphStyleAttributeName];
if (!style) {
style = [[NSMutableParagraphStyle alloc] init];
}
style.alignment = NSTextAlignmentJustified;
style.firstLineHeadIndent = 0.001; // important: must have a value to make alignment work
[self addAttribute:NSBaselineOffsetAttributeName value:@0 range:range];
}
@end
@implementation NSString (Attributed)
- (NSString *)trimBothEnd {
NSMutableString *string = [[NSMutableString alloc] initWithString:self];
string = [string trimSpace];
return string;
}
- (NSString *)trimInnerReturn {
NSString *string = self;
string = [self stringByReplacingOccurrencesOfString:@"\r" withString:@""];
string = [self stringByReplacingOccurrencesOfString:@"\n" withString:@""];
return string;
}
- (NSMutableAttributedString *)fontSize:(NSInteger)size {
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self attributes:@{NSFontAttributeName: GMFont(size)}];
return string;
}
@end
@implementation NSMutableAttributedString (Attributed)
- (NSMutableAttributedString *)addColor:(UIColor *)color {
[self addAttributes:@{NSForegroundColorAttributeName: color} range:NSMakeRange(0, self.length)];
return self;
}
- (NSMutableAttributedString *)addLineSpace:(NSInteger)space {
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = space;
style.lineBreakMode = NSLineBreakByTruncatingTail;
[self addAttributes:@{NSParagraphStyleAttributeName: style} range:NSMakeRange(0, self.length)];
return self;
}
- (NSMutableAttributedString *)addShadow:(CGFloat)blur {
NSShadow *shadow = [NSShadow new];
shadow.shadowOffset = CGSizeZero;
shadow.shadowBlurRadius = blur;
[self addAttributes:@{NSShadowAttributeName: shadow} range:NSMakeRange(0, self.length)];
return self;
}
@end
\ No newline at end of file
//
// NSDate+DateFormat.h
// Gengmei
//
// Created by Sean Lee on 4/14/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSDate (DateFormat)
/**
* @author licong, 16-12-29 16:12:03
*
* 日期格式化成年月日型的字符串(eg:2015-4-14)
*
* @return 返回格式化后的字符串
*
* @since 5.8
*/
-(NSString *)dateFormatToString;
/**
* @author licong, 16-12-29 16:12:07
*
* 日期格式化成年月日星期型的字符串(eg:2015年4月14号 星期三)
*
* @return 返回格式化后的字符串
*
* @since 5.8
*/
-(NSString *)dateFormatToWeekString;
@end
//
// NSDate+DateFormat.m
// Gengmei
//
// Created by Sean Lee on 4/14/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "NSDate+DateFormat.h"
@implementation NSDate (DateFormat)
-(NSString *)dateFormatToString {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd"];
return [formatter stringFromDate:self];
}
- (NSString *)dateFormatToWeekString{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps;
comps = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:self];
NSInteger nowYear = [comps year];
NSInteger nowMonth = [comps month];
NSInteger nowDay = [comps day];
NSInteger nowWeek = [comps weekday];
NSString *weekStr = [[NSString alloc] init];
switch (nowWeek) {
case 1:
weekStr = @"星期天";
break;
case 2:
weekStr = @"星期一";
break;
case 3:
weekStr = @"星期二";
break;
case 4:
weekStr = @"星期三";
break;
case 5:
weekStr = @"星期四";
break;
case 6:
weekStr = @"星期五";
break;
case 7:
weekStr = @"星期六";
break;
default:
break;
}
NSString * formatterDateString = [NSString stringWithFormat:@"%ld年%ld月%ld日",(long)nowYear,(long)nowMonth,(long)nowDay];
return formatterDateString;
}
@end
//
// NSFileManager+FolderSize.h
// ZhengXing
//
// Created by wangyang on 3/19/15.
// Copyright (c) 2015 Wanmei Creative. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSFileManager (FolderSize)
- (BOOL)getAllocatedSize:(unsigned long long *)size ofDirectoryAtURL:(NSURL *)directoryURL error:(NSError * __autoreleasing *)error;
@end
//
// NRFileManager.m
// NRFoundation
//
// Created by Nikolai Ruhe on 2015-02-22.
// Copyright (c) 2015 Nikolai Ruhe. All rights reserved.
//
#import "NSFileManager+FolderSize.h"
@implementation NSFileManager (FolderSize)
// This method calculates the accumulated size of a directory on the volume in bytes.
//
// As there's no simple way to get this information from the file system it has to crawl the entire hierarchy,
// accumulating the overall sum on the way. The resulting value is roughly equivalent with the amount of bytes
// that would become available on the volume if the directory would be deleted.
//
// Caveat: There are a couple of oddities that are not taken into account (like symbolic links, meta data of
// directories, hard links, ...).
- (BOOL)getAllocatedSize:(unsigned long long *)size ofDirectoryAtURL:(NSURL *)directoryURL error:(NSError * __autoreleasing *)error
{
NSParameterAssert(size != NULL);
NSParameterAssert(directoryURL != nil);
// We'll sum up content size here:
unsigned long long accumulatedSize = 0;
// prefetching some properties during traversal will speed up things a bit.
NSArray *prefetchedProperties = @[
NSURLIsRegularFileKey,
NSURLFileAllocatedSizeKey,
NSURLTotalFileAllocatedSizeKey,
];
// The error handler simply signals errors to outside code.
__block BOOL errorDidOccur = NO;
BOOL (^errorHandler)(NSURL *, NSError *) = ^(NSURL *url, NSError *localError) {
if (error != NULL)
*error = localError;
errorDidOccur = YES;
return NO;
};
// We have to enumerate all directory contents, including subdirectories.
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:directoryURL
includingPropertiesForKeys:prefetchedProperties
options:(NSDirectoryEnumerationOptions)0
errorHandler:errorHandler];
// Start the traversal:
for (NSURL *contentItemURL in enumerator) {
// Bail out on errors from the errorHandler.
if (errorDidOccur)
return NO;
// Get the type of this item, making sure we only sum up sizes of regular files.
NSNumber *isRegularFile;
if (! [contentItemURL getResourceValue:&isRegularFile forKey:NSURLIsRegularFileKey error:error])
return NO;
if (! [isRegularFile boolValue])
continue; // Ignore anything except regular files.
// To get the file's size we first try the most comprehensive value in terms of what the file may use on disk.
// This includes metadata, compression (on file system level) and block size.
NSNumber *fileSize;
if (! [contentItemURL getResourceValue:&fileSize forKey:NSURLTotalFileAllocatedSizeKey error:error])
return NO;
// In case the value is unavailable we use the fallback value (excluding meta data and compression)
// This value should always be available.
if (fileSize == nil) {
if (! [contentItemURL getResourceValue:&fileSize forKey:NSURLFileAllocatedSizeKey error:error])
return NO;
NSAssert(fileSize != nil, @"huh? NSURLFileAllocatedSizeKey should always return a value");
}
// We're good, add up the value.
accumulatedSize += [fileSize unsignedLongLongValue];
}
// Bail out on errors from the errorHandler.
if (errorDidOccur)
return NO;
// We finally got it.
*size = accumulatedSize;
return YES;
}
@end
//
// NSNull+Empty.h
// Gengmei
//
// Created by licong on 12/28/15.
// Copyright © 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSNull (Empty)
- (BOOL)isNonEmpty;
/**
* @brief 我们极力避免使用 string.length 的方式来判断空字符串。但是 string.length 除了用来判断,可能还会用在其它非判断的功能上。为了避免 [NSNull length] 而引起的 crash,还是给 NSNull 添加一个 length 方法比较安全。并且在 debug 情况下打印 log,以提示使用了 length 方法
*
* @return 0
*/
- (NSUInteger)length;
@end
//
// NSNull+Empty.m
// Gengmei
//
// Created by licong on 12/28/15.
// Copyright © 2015 Wanmeichuangyi. All rights reserved.
//
#import "NSNull+Empty.h"
@implementation NSNull (Empty)
- (BOOL) isNonEmpty {
return NO;
}
- (NSUInteger)length{
NSAssert(0, @"注意:向 NSNull 发送了 length 消息");
return 0;
}
@end
//
// UIViewController+KeyboardAnimation.h
// yingshibaokaoyan
//
// Created by wangyang on 7/17/14.
// Copyright (c) 2014 com.zkyj.yingshibao.kaoyao. All rights reserved.
//
#import <UIKit/UIKit.h>
/**
* 当键盘弹出或者收起时,会执行的block。在这个block里实现需要的UI变动
*
* @param offkeyboardFrameset 将键盘转换为视图所在坐标第后,整个键盘View的Frame
* @param duration 动画时间
* @param curve 动画效果
* @param notification 通知
*/
typedef void(^ShowKeyboardAnimation)(CGRect keyboardFrame, CGFloat duration, NSInteger curve, NSNotification *notifcation);
typedef void(^HideKeyboardAnimation)(CGFloat duration, NSInteger curve, NSNotification *notifcation);
/**
* 使用该类别,以方便的控制键盘事件
*/
@interface NSObject (KeyboardAnimation)
- (void)observeKeyboardForView:(UIView *)view showKeyboardAnimation:(ShowKeyboardAnimation)animation1 hideKeyboardAnimation:(HideKeyboardAnimation)animation2;
- (void)removeObservKeyboard;
@end
//
// UIViewController+KeyboardAnimation.m
// yingshibaokaoyan
//
// Created by wangyang on 7/17/14.
// Copyright (c) 2014 com.zkyj.yingshibao.kaoyao. All rights reserved.
//
#import "NSObject+KeyboardAnimation.h"
#import <objc/runtime.h>
static const char kwy_targetView;
static const char kwy_showAnimationblock;
static const char kwy_hideAnimationblock;
@interface NSObject ()
@property (nonatomic, strong) UIView *wy_targetView;
@property (nonatomic, copy) ShowKeyboardAnimation wy_showAnimationblock;
@property (nonatomic, copy) HideKeyboardAnimation wy_hideAnimationblock;
@end
@implementation NSObject (KeyboardAnimation)
#pragma mark - 属性get、set
- (ShowKeyboardAnimation)wy_showAnimationblock
{
return objc_getAssociatedObject(self, &kwy_showAnimationblock);
}
- (void)setWy_showAnimationblock:(ShowKeyboardAnimation)wy_showAnimationblock
{
objc_setAssociatedObject(self, &kwy_showAnimationblock, wy_showAnimationblock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (HideKeyboardAnimation)wy_hideAnimationblock
{
return objc_getAssociatedObject(self, &kwy_hideAnimationblock);
}
- (void)setWy_hideAnimationblock:(HideKeyboardAnimation)wy_hideAnimationblock
{
objc_setAssociatedObject(self, &kwy_hideAnimationblock, wy_hideAnimationblock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (UIView *)wy_targetView
{
return objc_getAssociatedObject(self, &kwy_targetView);
}
- (void)setWy_targetView:(UIView *)wy_targetView
{
objc_setAssociatedObject(self, &kwy_targetView, wy_targetView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark - 监听
- (void)observeKeyboardForView:(UIView *)view showKeyboardAnimation:(ShowKeyboardAnimation)animation1 hideKeyboardAnimation:(HideKeyboardAnimation)animation2
{
self.wy_showAnimationblock = animation1;
self.wy_targetView = view;
self.wy_hideAnimationblock = animation2;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)removeObservKeyboard
{
self.wy_showAnimationblock = nil;
self.wy_targetView = nil;
self.wy_hideAnimationblock = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
#pragma mark - 监听响应
- (void)keyboardWillShow:(NSNotification *)note{
// get keyboard size and loctaion
CGRect keyboardFrame;
[[note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardFrame];
// Need to translate the bounds to account for rotation.
keyboardFrame = [[UIApplication sharedApplication].keyWindow convertRect:keyboardFrame toView:self.wy_targetView.superview];
NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
self.wy_showAnimationblock(keyboardFrame, [duration doubleValue], [curve integerValue], note);
}
- (void)keyboardWillHide:(NSNotification *)note{
NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
self.wy_hideAnimationblock([duration doubleValue], [curve integerValue], note);
}
@end
//
// NSString+DateFormat.h
// Gengmei
//
// Created by Sean Lee on 4/15/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString (DateFormat)
/**
* @author licong, 16-12-29 16:12:14
*
* String类型的日期转为冒号式的NSDate
*
* @return 返回一个NSDate对象
*
* @since 5.8
*/
-(NSDate *)stringFormatToColonDate;
/**
* @author licong, 16-12-29 16:12:59
*
* String类型的日期转为破折号式的NSDate
*
* @return 返回一个NSDate对象
*
* @since 5.8
*/
-(NSDate *)stringformatToDashDate;
@end
//
// NSString+DateFormat.m
// Gengmei
//
// Created by Sean Lee on 4/15/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "NSString+DateFormat.h"
@implementation NSString (DateFormat)
-(NSDate *)stringFormatToColonDate{
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"YYYY-MM-dd"];
return [formatter dateFromString:self];
}
- (NSDate *)stringformatToDashDate{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY:MM:dd"];
return [dateFormatter dateFromString:self];
}
@end
//
// NSString+Encrypt.h
// Gengmei
//
// Created by licong on 12/28/15.
// Copyright © 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* @brief
AES块长度 128 byte
加密模式CBC,cipher block chaining
数据长度不到128byte时需要填充(即no padding自定义填充)
填充方法s + (128 - len(s) % 128) * chr(128 - len(s) % 128) 将数字转成char字符拼接尾部
加密密钥 Up[K+ub%pliOnsO5UavFBd)cw5VcyHSX
初始向量需要附加在加密后的auth_user_id中 传给服务器,final auth_user_id = base64(iv+encrypted(user_id_auth))
*/
@interface NSString (Encrypt)
/**
* @brief AES256加密
*
* @param keyString 32位的密钥
*
* @return 返回加密后的密文
*/
- (NSString *)AES256EncryptedStringForKey:(NSString *)key;
/**
* @brief AES256解密
*
* @param keyString 32位的密钥
*
* @return 返回解密后的明文
*/
- (NSString *)AES256DecryptedStringForKey:(NSString *)key;
/**
* @brief MD5加密
*
* @return MD5加密后的String
*/
- (NSString *) stringFromMD5;
@end
//
// NSString+Encrypt.m
// Gengmei
//
// Created by licong on 12/28/15.
// Copyright © 2015 Wanmeichuangyi. All rights reserved.
//
#import "NSString+Encrypt.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <Base64nl/Base64nl-umbrella.h>
@implementation NSString (Encrypt)
- (NSString *)AES256EncryptedStringForKey:(NSString *)key
{
//密钥
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
//明文数据
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
// Init cryptor
CCCryptorRef cryptor = NULL;
//IV:初始化16字节的随机向量
char iv[16];
for (int i = 0; i<16; i++) {
iv[i] = arc4random()%255;//一个字节长的随机数
}
//Create Cryptor
CCCryptorStatus create = CCCryptorCreateWithMode(kCCEncrypt,
kCCModeCBC, //CBC模式
kCCAlgorithmAES128, //分组密码块长度
ccNoPadding, //无填充模式
iv, // can be NULL, because null is full of zeros
keyData.bytes, //密钥
keyData.length, //密钥长度
NULL,
0,
0,
0, //这里参数只在CTR下有用,本初填0即可
&cryptor);
if (create == kCCSuccess){
size_t numBytesCrypted;
//自定义填充明文算法
NSUInteger dataLength = [data length];
int diff = 128 - (dataLength % 128);
unsigned long newSize = 0;
if(diff > 0)
newSize = dataLength + diff;
char dataPtr[newSize];
memcpy(dataPtr, [data bytes], [data length]);
for(int i = 0; i < diff; i++){
char character = diff;
dataPtr[i + dataLength] = character;
}
/*初始化加密后的data,并开辟好空间长度,查阅相关文档:对于分组密码,加密后的数据长度总是小于或者等于 加密前数据长度+单个分组密码块长度之和*/
NSMutableData *cipherData= [NSMutableData dataWithLength: sizeof(dataPtr)+kCCBlockSizeAES128];
/*Update Cryptor,得到加密后data以及我们需要的数据长度,这里可以看到cipherData的长度是小于或者等于outLength的
*/
CCCryptorStatus update = CCCryptorUpdate(cryptor,
dataPtr,
sizeof(dataPtr),
cipherData.mutableBytes,
cipherData.length,
&numBytesCrypted);
if (update == kCCSuccess){
//通过outLength截图我们需要的数据长度
cipherData.length = numBytesCrypted;
//Final Cryptor,最终生成最终的密文,装载给cipherData
CCCryptorStatus final = CCCryptorFinal(cryptor, //CCCryptorRef cryptorRef,
cipherData.mutableBytes, //void *dataOut,
cipherData.length, //size_t dataOutAvailable,
&numBytesCrypted); //size_t *dataOutMoved)
if (final == kCCSuccess){
//Release Cryptor
CCCryptorRelease(cryptor);
}
//最终结果= 初始向量+密文,这样服务器才可以拿到初始向量,用密钥解码
NSMutableData *resultData= [NSMutableData dataWithLength:0];
[resultData appendBytes:iv length:sizeof(iv)];
[resultData appendBytes:cipherData.bytes length:cipherData.length];
//最终结果再base64转码
NSString * resultStr = [resultData base64EncodedString];//[GTMBase64 stringByEncodingData:resultData];
return resultStr;
}
}
else{
NSLog(@"加密失败");
}
return nil;
}
- (NSString *)AES256DecryptedStringForKey:(NSString *)key {
//Key to Data
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
// Init cryptor
CCCryptorRef cryptor = NULL;
//IV:获取密文里的随机向量
NSData *data = [self base64DecodedData];
NSMutableData * iv = [NSMutableData dataWithBytes:data.bytes length:kCCKeySizeAES256];
// Create Cryptor
CCCryptorStatus createDecrypt = CCCryptorCreateWithMode(kCCDecrypt, // operation
kCCModeCBC, // mode CTR
kCCAlgorithmAES, // Algorithm
ccNoPadding, // padding
iv.bytes, // can be NULL, because null is full of zeros
keyData.bytes, // key
keyData.length, // keylength
NULL, //const void *tweak
0, //size_t tweakLength,
0, //int numRounds,
0, //CCModeOptions options,
&cryptor); //CCCryptorRef *cryptorRef
if (createDecrypt == kCCSuccess)
{
// Alloc Data Out
NSMutableData * realData = [NSMutableData dataWithBytes:data.bytes + 16 length:data.length - 16];
NSMutableData *cipherDataDecrypt = [NSMutableData dataWithLength:realData.length + kCCBlockSizeAES128];
//alloc number of bytes written to data Out
size_t outLengthDecrypt;
//Update Cryptor
CCCryptorStatus updateDecrypt = CCCryptorUpdate(cryptor,
realData.bytes, //const void *dataIn,
realData.length, //size_t dataInLength,
cipherDataDecrypt.mutableBytes, //void *dataOut,
cipherDataDecrypt.length, // size_t dataOutAvailable,
&outLengthDecrypt); // size_t *dataOutMoved)
if (updateDecrypt == kCCSuccess)
{
//Cut Data Out with nedded length
cipherDataDecrypt.length = outLengthDecrypt;
//Final Cryptor
CCCryptorStatus final = CCCryptorFinal(cryptor, //CCCryptorRef cryptorRef,
cipherDataDecrypt.mutableBytes, //void *dataOut,
cipherDataDecrypt.length, // size_t dataOutAvailable,
&outLengthDecrypt); // size_t *dataOutMoved)
if (final == kCCSuccess){
CCCryptorRelease(cryptor); //CCCryptorRef cryptorRef
}
// Data to String
NSMutableString* cipherFinalDecrypt = [[NSMutableString alloc] initWithData:cipherDataDecrypt encoding:NSUTF8StringEncoding];
int diff = [cipherFinalDecrypt characterAtIndex:cipherDataDecrypt.length - 1]; // 128字节的明文(填充字符)中填充字符的个数
[cipherFinalDecrypt deleteCharactersInRange:NSMakeRange(cipherFinalDecrypt.length - diff, diff)];
return cipherFinalDecrypt;
}
}
else{
NSLog(@"解密密失败");
}
return nil;
}
- (NSString *)stringFromMD5
{
if(self == nil || [self length] == 0)
return nil;
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, (uint32_t)strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return outputString;
}
+ (BOOL)validKey:(NSString*)key
{
if(key == nil || key.length != kCCKeySizeAES256){
return NO;
}
return YES;
}
@end
//
// NSString+GM.h
// Gengmei
//
// Created by licong on 12/28/15.
// Copyright © 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* 常用且按功能块比较难划分的扩展方法
*/
@interface NSString (GM)
/**
* @author licong, 16-12-28 12:12:13
*
* 判断一个字符串是否为空(包括nil/@""/nil)
*
* @return 布尔值,YES表示字符串不为空,NO表示字符串为空
*
* @since 5.8
*/
- (BOOL)isNonEmpty;
/*!
* @author zhaiguojun, 16-04-21
*
* @brief 把字典和数组转成string
*
* @param object
*
* @return 转换后的string
*
* @since 5.9.3
*/
+ (NSString*)dataToJsonString:(id)object;
/**
* @author licong, 16-12-28 12:12:16
*
* 得到非空string
*
* @return 返回一个非空的字符串
*
* @since 5.8
*/
+ (NSString *)safeStringWithString:(NSString *)string;
/**
* @author licong, 16-12-28 18:12:04
*
* 去除字符串中间和收尾的空格
*
* @return 无空格的字符串
*
* @since 5.8
*/
- (NSString*)trimSpace;
/**
* @brief 是否为纯数字
*
* @param string 要检查的字符串
*
*/
+ (BOOL)isPureInt:(NSString *)string;
/**
* @brief 是否为手机号
*
* @param 0~9 11位即可
*
*
* @return
*/
+ (BOOL)isMobileNumber:(NSString *)mobileNum;
@end
/**
*
* 将类似URL的query参数解析成字典
*
*/
@interface NSString (paresQuery)
/**
* @author licong, 16-12-28 18:12:14
*
* 解析url中的query,转成字典格式
*
* @return 解析好的字典
*
* @since 5.8
*/
- (NSDictionary*)urlQueryToDictionary;
/**
* @author licong, 16-12-28 18:12:11
*
* 解析query字符串为字典比如:a=b&c=d
*
* @return 解析好的字典
*
* @since 5.8
*/
- (NSDictionary*)queryToDictionary;
@end
/**
*
* 根据String的Font计算String的size
*
*/
@interface NSString (calculatorSize)
/**
* @author licong, 16-12-28 18:12:38
*
* 计算String当行间距为0的时候的高度和宽度
*
* @param font String的font
* @param size String限定的size
*
* @return String实际(如果是多行,则经过折行后)的size
*
* @since 5.8
*/
- (CGSize)sizeWithFont:(UIFont *)font boundSize:(CGSize)size;
/**
* @author licong, 16-12-28 18:12:05
*
* 计算String在某个行间距下,高度和宽度
*
* @param font String的font
* @param size String限定的size
* @param lineSpacing 设定的行间距
*
* @return String在设定的行间距下,实际(如果是多行,则经过折行后)的size
*
* @since 5.8
*/
- (CGSize)sizeWithFont:(UIFont *)font boundSize:(CGSize)size lineSpacing:(CGFloat)lineSpacing;
@end
@interface NSString (URLEncoding)
/**
* @author licong, 16-12-29 16:12:45
*
* URL编码
*
* @return 编码后的URL
*
* @since 5.8
*/
- (NSString*) URLEncodedString;
/**
* @author licong, 16-12-29 16:12:08
*
* URL解码
*
* @return 解码URL
*
* @since 5.8
*/
- (NSString*) URLDecodedString;
@end
//
// NSString+GM.m
// Gengmei
//
// Created by licong on 12/28/15.
// Copyright © 2015 Wanmeichuangyi. All rights reserved.
//
#import "NSString+GM.h"
#import "NSNull+Empty.h"
@implementation NSString (GM)
+ (NSString *)safeStringWithString:(NSString *)string{
if ([string isNonEmpty]) {
return string;
}else{
return @"";
}
}
- (BOOL)isNonEmpty {
NSMutableCharacterSet *emptyStringSet = [[NSMutableCharacterSet alloc] init];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet characterSetWithCharactersInString: @" "]];
if ([self length] == 0) {
return NO;
}
NSString* str = [self stringByTrimmingCharactersInSet:emptyStringSet];
return [str length] > 0;
}
+ (NSString*)dataToJsonString:(id)object
{
NSString *jsonString = nil;
NSError *error;
if (!object) {
return nil;
}
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object
options:NSJSONWritingPrettyPrinted
error:&error];
if (! jsonData) {
NSLog(@"Got an error: %@", error);
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
return jsonString;
}
- (NSString*) trimSpace {
NSMutableCharacterSet* emptyStringSet = [[NSMutableCharacterSet alloc] init];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet characterSetWithCharactersInString: @" "]];
return [self stringByTrimmingCharactersInSet: emptyStringSet];
}
+ (BOOL)isPureInt:(NSString *)string{
NSScanner* scan = [NSScanner scannerWithString:string];
int val;
return [scan scanInt:&val] && [scan isAtEnd];
}
+ (BOOL)isMobileNumber:(NSString *)mobileNum{
NSString *ALL = @"\\d{11}$";
NSPredicate *regextestall = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", ALL];
return [regextestall evaluateWithObject:mobileNum];
}
@end
@implementation NSString (paresQuery)
- (NSDictionary*)urlQueryToDictionary{
NSURL* url1 = [NSURL URLWithString:self];
if (!url1) {
return nil;
}
NSString* query = [url1 query];
return [query queryToDictionary];
}
- (NSDictionary*)queryToDictionary {
@try {
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
NSArray* components = [self componentsSeparatedByString:@"&"];
for (NSString* component in components) {
NSArray* keyValue = [component componentsSeparatedByString:@"="];
if ([keyValue count] > 1) {
NSString * key = [[keyValue objectAtIndex:0] URLDecodedString];
NSString * value = [keyValue objectAtIndex:1];
//参数中依然包含超过2个“=”号(多数发生在common_webview后的url参数中),则后面的数组的元素需要拼接成一个字符串
if ([keyValue count]>2) {
for (int i=2; i<[keyValue count]; i++) {
value=[value stringByAppendingString:@"="];
value=[value stringByAppendingString:keyValue[i]];
}
}
//因为这种情况服务器和客户端都转义了一次,所以要两次反转义还原中文
while ([value rangeOfString:@"%"].length != 0) {
value = [value URLDecodedString];
}
[dict setObject: value forKey: key];
}
}
return dict;
}
@catch (NSException *exception) {}
}
@end
@implementation NSString (calculatorSize)
- (CGSize)sizeWithFont:(UIFont *)font boundSize:(CGSize)size{
return [self sizeWithFont:font boundSize:size lineSpacing:0];
}
- (CGSize)sizeWithFont:(UIFont *)font boundSize:(CGSize)size lineSpacing:(CGFloat)lineSpacing{
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineSpacing = lineSpacing;
NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle};
CGSize resultSize = [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine attributes:attributes context:nil].size;
return CGSizeMake(ceil(resultSize.width), ceil(resultSize.height));
}
@end
@implementation NSString (URLEncoding)
- (NSString *)URLEncodedString {
NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)self,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8));
return result;
}
- (NSString*)URLDecodedString {
NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,
(CFStringRef)self,
CFSTR(""),
kCFStringEncodingUTF8));
return result;
}
@end
Copyright (c) 2016 licong <1240690490@qq.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# GMFoundation
[![CI Status](http://img.shields.io/travis/licong/GMFoundation.svg?style=flat)](https://travis-ci.org/licong/GMFoundation)
[![Version](https://img.shields.io/cocoapods/v/GMFoundation.svg?style=flat)](http://cocoapods.org/pods/GMFoundation)
[![License](https://img.shields.io/cocoapods/l/GMFoundation.svg?style=flat)](http://cocoapods.org/pods/GMFoundation)
[![Platform](https://img.shields.io/cocoapods/p/GMFoundation.svg?style=flat)](http://cocoapods.org/pods/GMFoundation)
## Example
To run the example project, clone the repo, and run `pod install` from the Example directory first.
## Requirements
## Installation
GMFoundation is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod "GMFoundation"
```
## Author
licong, 1240690490@qq.com
## License
GMFoundation is available under the MIT license. See the LICENSE file for more info.
Copyright (c) 2016 北京更美互动信息科技有限公司
仅限北京更美互动信息科技有限公司内部使用
//
// UIDevice+Reso.m
// Simple UIDevice Category for handling different iOSs hardware resolutions
//
// Created by Alejandro Luengo on 29/09/14.
// (c) 2014 Intelygenz
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, UIDeviceResolution) {
UnknowDevice = 0,
iPhone4 = 1,
iPhone5 = 2,
iPhone6 = 3,
iPhone6Plus = 4,
iPad = 5,
iPadRetina = 6
};
@interface UIDevice (Resolutions)
/**
* @author licong, 16-12-29 17:12:54
*
* 判断设备的类型(eg:当前设备是5还是6s)
*
* @return 返回设备类型
*
* @since 5.8
*/
+ (UIDeviceResolution)type;
/**
获取设备的deviceId,如果能去到idfa,就返回idfa,否则就返回idfv
@author zhaiguojun 16-10-31 in (null)
@return deviceId
@since 6.5.0
*/
+ (NSString *)deviceId;
/**
* @author licong, 16-12-29 16:12:13
*
* 获取设备的名字
*
* @return 返回设备名字
*
* @since 5.8
*/
+ (NSString*)deviceName;
/**
获取设备详细类型,目前只到6s,和6s plus
@author zhaiguojun 16-09-18 in (null)
@return model
@since 6.3.0
*/
+ (NSString*)deviceVersion;
@end
//
// UIDevice+Reso.m
// Simple UIDevice Category for handling different iOSs hardware resolutions
//
// Created by Alejandro Luengo on 29/09/14.
// (c) 2014 Intelygenz
// iPhone 6 Plus 736x414 points 2208x1242 pixels 3x scale
// iPhone 6 667x375 points 1334x750 pixels 2x scale
// iPhone 5 568x320 points 1136x640 pixels 2x scale
// iPhone 4s 480x320 points 960x640 pixels 2x scale
// iPad 1024x768 points 1024x768 pixels 1x scale
// iPad Retina 1024x768 points 2048x1536 pixels 2x scale
#import "UIDevice+Resolutions.h"
#import "sys/utsname.h"
#import <AdSupport/AdSupport.h>
@implementation UIDevice (Resolutions)
+ (NSString*)deviceName{
NSDictionary *devices = @{@"iPhone 4": @"960",
@"iPhone 5": @"1136",
@"iPhone 6": @"1334",
@"iPhone 6 Plus": @"2208",
@"iPad": @"1024",
@"iPad Retina": @"2048"
};
UIScreenMode *mode = [UIScreen mainScreen].preferredMode;
return [[devices allKeysForObject:[NSString stringWithFormat:@"%.f", mode.size.height]] firstObject];
}
+ (NSString *)deviceId {
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
if (![idfa isEqualToString:@"00000000-0000-0000-0000-000000000000"]) {
return idfa;
}
return idfv;
}
+ (UIDeviceResolution)type
{
UIScreenMode *mode = [UIScreen mainScreen].preferredMode;
if (mode.size.height == 960) {
return iPhone4;
}
else if (mode.size.height == 1136) {
return iPhone5;
}
else if (mode.size.height == 1334) {
return iPhone6;
}
else if (mode.size.height == 2208) {
return iPhone6Plus;
}
else if (mode.size.height == 1024) {
return iPad;
}
else if (mode.size.height == 2048) {
return iPadRetina;
}
else
return UnknowDevice;
}
+ (NSString*)deviceVersion
{
struct utsname systemInfo;
uname(&systemInfo);
NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
//iPhone
if ([deviceString isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([deviceString isEqualToString:@"iPhone3,2"]) return @"Verizon iPhone 4";
if ([deviceString isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([deviceString isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
if ([deviceString isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
if ([deviceString isEqualToString:@"iPhone5,3"]) return @"iPhone 5C";
if ([deviceString isEqualToString:@"iPhone5,4"]) return @"iPhone 5C";
if ([deviceString isEqualToString:@"iPhone6,1"]) return @"iPhone 5S";
if ([deviceString isEqualToString:@"iPhone6,2"]) return @"iPhone 5S";
if ([deviceString isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
if ([deviceString isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
if ([deviceString isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
if ([deviceString isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
if ([deviceString isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
if ([deviceString isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
return @"iphone 7 ++";
}
@end
//
// UIImage+GM.h
// Gengmei
//
// Created by licong on 15/12/29. Rewrite by wangyang on 2016-7-4
// Copyright © 2016年 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (GM)
/**
* @brief 通过颜色生成图片
*
* @param color 颜色
*/
+ (UIImage *)imageWithColor:(UIColor *)color;
/**
* @author licong, 16-12-29 18:12:48
*
* 将图片调整到设定大小
*
* @param size 设定的图片大小
*
* @return 得到设定大小后的图片
*
* @since 5.8
*/
- (UIImage *)resizedImageWithSize:(CGSize)size;
/**
* @author wangyang in 2016-7-1
*
* 参考rotatedWithTransform
*/
- (UIImage *)rotatedWithAngle:(double)angle;
/**
* @author wangyang in 2016-7-1
*
* 使用这个方法旋转图片,导出的图片的imageOrientation为Up,绘制时会同时考虑待旋转图片的原 imageOrientation 与参数 transform
@note
1. 使用这个方法进行旋转,导出的图片大小可能会发生变化。比如旋转45度,那么能容下原图的bounds肯定要大一些;比如旋转90度,图片的高宽就会互换。
2. 旋转角度为0时,可以用来将图片的imageOrientation重置为Up。
* @return 新图片
*/
- (UIImage *)rotatedWithTransform:(CGAffineTransform)transform;
/**
* @author wangyang in 2016-7-4
*
* 裁剪图片
*/
- (UIImage *)imageWithCropRect:(CGRect)rect;
@end
\ No newline at end of file
//
// UIImage+GM.m
// Gengmei
//
// Created by licong on 15/12/29. Rewrite by wangyang on 2016-7-4
// Copyright © 2016年 Wanmeichuangyi. All rights reserved.
//
#import "UIImage+GM.h"
@implementation UIImage (GM)
#pragma mark - 从颜色生成图片
+ (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#pragma mark - 改变大小
- (UIImage *)resizedImageWithSize:(CGSize)size {
UIGraphicsBeginImageContext(size);
CGRect rect = CGRectMake(0, 0, size.width, size.height);
// CGContextDrawImage时需要额外考虑UIImage.imageOrientation,drawInRect可以自动帮我们做好这件事
[self drawInRect:rect];
// 另外,我们不需要指定使用 CGContextSetInterpolationQuality,使用默认值Hight就可以。参考http://stackoverflow.com/questions/5685884/imagequality-with-cgcontextsetinterpolationquality
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImg;
}
#pragma mark - 旋转
- (UIImage *)rotatedWithAngle:(double)angle
{
CGAffineTransform transform = CGAffineTransformMakeRotation(angle * M_PI / 180);
return [self rotatedWithTransform:transform];
}
- (UIImage *)rotatedWithTransform:(CGAffineTransform)transform {
// 旋转后图片的大小
CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0, 0, self.size.width, self.size.height), transform);
rotatedRect.origin.x = 0;
rotatedRect.origin.y = 0;
CGSize rotatedSize = rotatedRect.size;
UIGraphicsBeginImageContextWithOptions(rotatedSize, YES, self.scale);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
// 将 origin 图片的移动中间, 这样我们就可以绕着中心点旋转
CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);
// 旋转画布布
CGContextConcatCTM(bitmap, transform);
// 再将 origin 移回来
CGContextTranslateCTM(bitmap, rotatedSize.width / -2, rotatedSize.height / -2);
// drawInRect 会考虑图片的 orientation,也会考虑当前Context的变换
[self drawInRect:rotatedRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
#pragma mark - 剪切
- (UIImage *)imageWithCropRect:(CGRect)rect
{
CGImageRef croppedImage = CGImageCreateWithImageInRect(self.CGImage, rect);
UIImage *image = [UIImage imageWithCGImage:croppedImage];
CGImageRelease(croppedImage);
return image;
}
@end
//
// UILabel+CopyExtern.h
// CopyLabel
//
// Created by XingBo on 14-4-1.
// Copyright (c) 2014年 XingBo. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UILabel (CopyExtern)
- (void)attachTapHandler;
@end
//
// UILabel+CopyExtern.m
// CopyLabel
//
// Created by XingBo on 14-4-1.
// Copyright (c) 2014年 XingBo. All rights reserved.
//
#import "UILabel+CopyExtern.h"
@implementation UILabel (CopyExtern)
-(BOOL)canBecomeFirstResponder
{
return YES;
}
// 可以响应的方法
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return (action == @selector(copyText:));
}
//针对于响应方法的实现
-(void)copyText:(id)sender
{
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
/**
fix帖子详情页 楼主发帖复制崩溃bug
因为某些富文本label只设置了attributedText,导致self.text为nil崩溃
*/
if (self.text) {
pboard.string = self.text;
}else{
pboard.string = self.attributedText.string;
}
}
//UILabel默认是不接收事件的,我们需要自己添加touch事件
-(void)attachTapHandler{
self.userInteractionEnabled = YES; //用户交互的总开关
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self addGestureRecognizer:longPress];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillShowMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillHideMenuNotification object:nil];
}
#pragma mark - notifation methods
- (void)menuShow:(NSNotification *)sender
{
if (self.isFirstResponder) {
self.backgroundColor = [UIColor grayColor];
}
}
- (void)menuHide:(NSNotification *)sender
{
self.backgroundColor = [UIColor clearColor];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)handleTap:(UIGestureRecognizer*) recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan) {
[self becomeFirstResponder];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuShow:) name:UIMenuControllerWillShowMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuHide:) name:UIMenuControllerWillHideMenuNotification object:nil];
[[UIMenuController sharedMenuController] setMenuItems:nil];
UIMenuItem *copyLink = [[UIMenuItem alloc] initWithTitle:@"复制"
action:@selector(copyText:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:copyLink, nil]];
[[UIMenuController sharedMenuController] setTargetRect:self.frame inView:self.superview];
[[UIMenuController sharedMenuController] setMenuVisible:YES animated: YES];
// label复制选中时的背景颜色
self.backgroundColor = [UIColor clearColor];
}
}
@end
//
// UITextView+Keyboard.h
// ZhengXing
//
// Created by Tulipa on 14-8-22.
// Copyright (c) 2014年 Wanmei Creative. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UITextView (Keyboard)
@property (nonatomic, assign) BOOL hasCloseButton;
@end
@interface UITextField (Keyboard)
@property (nonatomic, assign) BOOL hasCloseButton;
@end
//
// UITextView+Keyboard.m
// ZhengXing
//
// Created by Tulipa on 14-8-22.
// Copyright (c) 2014年 Wanmei Creative. All rights reserved.
//
#import "UITextView+Keyboard.h"
#import "UIView+Layout.h"
@implementation UITextView (Keyboard)
- (BOOL)hasCloseButton
{
return self.inputAccessoryView != nil;
}
- (void)setHasCloseButton:(BOOL)hasCloseButton
{
if (hasCloseButton)
{
UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeButton setBackgroundImage:[UIImage imageNamed:@"keyboard"] forState:UIControlStateNormal];
[closeButton sizeToFit];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, closeButton.height)];
[view addSubview:closeButton];
[view setBackgroundColor:[UIColor clearColor]];
[closeButton setRight:view.width];
[closeButton setTop:0];
[closeButton addTarget:self action:@selector(resignFirstResponder) forControlEvents:UIControlEventTouchUpInside];
self.inputAccessoryView = view;
}
else
{
self.inputAccessoryView = nil;
}
}
@end
@implementation UITextField (Keyboard)
- (BOOL)hasCloseButton
{
return self.inputAccessoryView != nil;
}
- (void)setHasCloseButton:(BOOL)hasCloseButton
{
if (hasCloseButton)
{
UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeButton setBackgroundImage:[UIImage imageNamed:@"keyboard"] forState:UIControlStateNormal];
[closeButton sizeToFit];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, closeButton.height)];
[view addSubview:closeButton];
[view setBackgroundColor:[UIColor clearColor]];
[closeButton setRight:view.width];
[closeButton setTop:0];
[closeButton addTarget:self action:@selector(resignFirstResponder) forControlEvents:UIControlEventTouchUpInside];
self.inputAccessoryView = view;
}
else
{
self.inputAccessoryView = nil;
}
}
@end
//
// UIView+Layout.h
// Gengmei
//
// Created by licong on 15/12/29.
// Copyright © 2015年 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (Layout)
/**
* Shortcut for frame.origin.x.
*
* Sets frame.origin.x = left
*/
@property (nonatomic) CGFloat left;
/**
* Shortcut for frame.origin.y
*
* Sets frame.origin.y = top
*/
@property (nonatomic) CGFloat top;
/**
* Shortcut for frame.origin.x + frame.size.width
*
* Sets frame.origin.x = right - frame.size.width
*/
@property (nonatomic) CGFloat right;
/**
* Shortcut for frame.origin.y + frame.size.height
*
* Sets frame.origin.y = bottom - frame.size.height
*/
@property (nonatomic) CGFloat bottom;
/**
* Shortcut for frame.size.width
*
* Sets frame.size.width = width
*/
@property (nonatomic) CGFloat width;
/**
* Shortcut for frame.size.height
*
* Sets frame.size.height = height
*/
@property (nonatomic) CGFloat height;
/**
* Shortcut for center.x
*
* Sets center.x = centerX
*/
@property (nonatomic) CGFloat centerX;
/**
* Shortcut for center.y
*
* Sets center.y = centerY
*/
@property (nonatomic) CGFloat centerY;
/**
* Return the x coordinate on the screen.
*/
@property (nonatomic, readonly) CGFloat screenX;
/**
* Return the y coordinate on the screen.
*/
@property (nonatomic, readonly) CGFloat screenY;
/**
* Return the x coordinate on the screen, taking into account scroll views.
*/
@property (nonatomic, readonly) CGFloat screenViewX;
/**
* Return the y coordinate on the screen, taking into account scroll views.
*/
@property (nonatomic, readonly) CGFloat screenViewY;
/**
* Return the view frame on the screen, taking into account scroll views.
*/
@property (nonatomic, readonly) CGRect screenFrame;
/**
* Shortcut for frame.origin
*/
@property (nonatomic) CGPoint origin;
/**
* Shortcut for frame.size
*/
@property (nonatomic) CGSize size;
/**
* Return the width in portrait or the height in landscape.
*/
@property (nonatomic, readonly) CGFloat orientationWidth;
/**
* Return the height in portrait or the width in landscape.
*/
@property (nonatomic, readonly) CGFloat orientationHeight;
/**
* Finds the first descendant view (including this view) that is a member of a particular class.
*/
- (UIView*)descendantOrSelfWithClass:(Class)cls;
/**
* Finds the first ancestor view (including this view) that is a member of a particular class.
*/
- (UIView*)ancestorOrSelfWithClass:(Class)cls;
/**
* Removes all subviews.
*/
- (void)removeAllSubviews;
@end
@interface UIView (GestureAction)
/**
Attaches the given block for a single tap action to the receiver.
@param block The block to execute.
*/
- (void)setTapActionWithBlock:(void (^)(void))block;
//- (void)removeTapAction;
/**
Attaches the given block for a long press action to the receiver.
@param block The block to execute.
*/
- (void)setLongPressActionWithBlock:(void (^)(void))block;
@end
//
// UIView+Layout.m
// Gengmei
//
// Created by licong on 15/12/29.
// Copyright © 2015年 Wanmeichuangyi. All rights reserved.
//
#import "UIView+Layout.h"
#import <objc/runtime.h>
static char kDTActionHandlerTapBlockKey;
static char kDTActionHandlerTapGestureKey;
static char kDTActionHandlerLongPressBlockKey;
static char kDTActionHandlerLongPressGestureKey;
@implementation UIView (Layout)
- (CGFloat)left {
return self.frame.origin.x;
}
- (void)setLeft:(CGFloat)x {
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (CGFloat)top {
return self.frame.origin.y;
}
- (void)setTop:(CGFloat)y {
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
- (CGFloat)right {
return self.frame.origin.x + self.frame.size.width;
}
- (void)setRight:(CGFloat)right {
CGRect frame = self.frame;
frame.origin.x = right - frame.size.width;
self.frame = frame;
}
- (CGFloat)bottom {
return self.frame.origin.y + self.frame.size.height;
}
- (void)setBottom:(CGFloat)bottom {
CGRect frame = self.frame;
frame.origin.y = bottom - frame.size.height;
self.frame = frame;
}
- (CGFloat)centerX {
return self.center.x;
}
- (void)setCenterX:(CGFloat)centerX {
self.center = CGPointMake(centerX, self.center.y);
}
- (CGFloat)centerY {
return self.center.y;
}
- (void)setCenterY:(CGFloat)centerY {
self.center = CGPointMake(self.center.x, centerY);
}
- (CGFloat)width {
return self.frame.size.width;
}
- (void)setWidth:(CGFloat)width {
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)height {
return self.frame.size.height;
}
- (void)setHeight:(CGFloat)height {
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
- (CGFloat)screenX {
CGFloat x = 0.0f;
for (UIView* view = self; view; view = view.superview) {
x += view.left;
}
return x;
}
- (CGFloat)screenY {
CGFloat y = 0.0f;
for (UIView* view = self; view; view = view.superview) {
y += view.top;
}
return y;
}
- (CGFloat)screenViewX {
CGFloat x = 0.0f;
for (UIView* view = self; view; view = view.superview) {
x += view.left;
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView* scrollView = (UIScrollView*)view;
x -= scrollView.contentOffset.x;
}
}
return x;
}
- (CGFloat)screenViewY {
CGFloat y = 0;
for (UIView* view = self; view; view = view.superview) {
y += view.top;
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView* scrollView = (UIScrollView*)view;
y -= scrollView.contentOffset.y;
}
}
return y;
}
- (CGRect)screenFrame {
return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height);
}
- (CGPoint)origin {
return self.frame.origin;
}
- (void)setOrigin:(CGPoint)origin {
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}
- (CGSize)size {
return self.frame.size;
}
- (void)setSize:(CGSize)size {
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
- (CGFloat)orientationWidth {
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)
? self.height : self.width;
}
- (CGFloat)orientationHeight {
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)
? self.width : self.height;
}
- (UIView*)descendantOrSelfWithClass:(Class)cls {
if ([self isKindOfClass:cls])
return self;
for (UIView* child in self.subviews) {
UIView* it = [child descendantOrSelfWithClass:cls];
if (it)
return it;
}
return nil;
}
- (UIView*)ancestorOrSelfWithClass:(Class)cls {
if ([self isKindOfClass:cls]) {
return self;
} else if (self.superview) {
return [self.superview ancestorOrSelfWithClass:cls];
} else {
return nil;
}
}
- (void)removeAllSubviews {
while (self.subviews.count) {
UIView* child = self.subviews.lastObject;
[child removeFromSuperview];
}
}
- (CGPoint)offsetFromView:(UIView*)otherView {
CGFloat x = 0.0f, y = 0.0f;
for (UIView* view = self; view && view != otherView; view = view.superview) {
x += view.left;
y += view.top;
}
return CGPointMake(x, y);
}
@end
@implementation UIView (GestureAction)
- (void)setTapActionWithBlock:(void (^)(void))block
{
UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerTapGestureKey);
if (!gesture)
{
gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForTapGesture:)];
[self addGestureRecognizer:gesture];
objc_setAssociatedObject(self, &kDTActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN);
}
objc_setAssociatedObject(self, &kDTActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY);
}
- (void)__handleActionForTapGesture:(UITapGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateRecognized)
{
void(^action)(void) = objc_getAssociatedObject(self, &kDTActionHandlerTapBlockKey);
if (action)
{
action();
}
}
}
- (void)setLongPressActionWithBlock:(void (^)(void))block
{
UILongPressGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerLongPressGestureKey);
if (!gesture)
{
gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForLongPressGesture:)];
[self addGestureRecognizer:gesture];
objc_setAssociatedObject(self, &kDTActionHandlerLongPressGestureKey, gesture, OBJC_ASSOCIATION_RETAIN);
}
objc_setAssociatedObject(self, &kDTActionHandlerLongPressBlockKey, block, OBJC_ASSOCIATION_COPY);
}
- (void)__handleActionForLongPressGesture:(UITapGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan)
{
void(^action)(void) = objc_getAssociatedObject(self, &kDTActionHandlerLongPressBlockKey);
if (action)
{
action();
}
}
}
@end
//
// UIView+LineWithAutolayout.h
// ZhengXing
//
// Created by wangyang on 11/6/14.
// Copyright (c) 2014 Wanmei Creative. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (LineWithAutolayout)
/**
* @author licong, 16-12-28 19:12:48
*
* alloc一个无固定大小的view,用作分割线
*
* @return 返回一个view
*
* @since 5.8
*/
- (UIView *)addLineWithoutFrame;
/**
* @author licong, 16-12-28 19:12:16
*
* 在指定view(就是self)的最上边缘,加一根与指定view宽度相等的头部边缘线
*
* @return 返回alloc的分割线
*
* @since 5.8
*/
- (UIView *)addTopLine;
/**
* @author licong, 16-12-28 19:12:16
*
* 在view(就是self)的最下边缘,加一根与指定view宽度相等的底部边缘线
*
* @return 返回alloc的分割线
*
* @since 5.8
*/
- (UIView *)addBottomLine;
/**
* @author licong, 16-12-28 19:13:30
*
* 给指定的view(就是self),加一跟中心水平线
*
* @param left 竖直线距离设定的view左边的距离
* @param right 竖直线距离设定的view右边的距离
*
* @return 返回alloc的中心竖直线
*
* @since 5.8
*/
- (UIView *)addCenterHorizontalLineWithLeft:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-28 19:12:40
*
* 给指定的view(就是self),加一跟中心竖直线
*
* @param top 竖直线距离设定的view上边的距离
* @param bottom 竖直线距离设定的view下边的距离
*
* @return 返回alloc的中心竖直线
*
* @since 5.8
*/
- (UIView *)addCenterVerticalLineWithTop:(CGFloat)top bottom:(CGFloat)bottom;
/**
* @author licong, 16-12-28 19:12:19
*
* 给指定的view(就是self)的最下边缘,加一根长度可设置的头部边缘线(最长不超过该view的宽度)
*
* @param left 头部边缘线距离设定view左边的距离
* @param right 头部边缘线距离设定view左边的距离
*
* @return 返回长度可设置的头部边缘线
*
* @since 5.8
*/
- (UIView *)addTopLineWithLeft:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-28 19:12:16
*
* 给指定的view(就是self)的最下边缘,加一根长度可设置的底部边缘线(最长不超过该view的宽度)
*
* @param left 底部边缘线距离设定view左边缘的距离
* @param right 底部边缘线距离设定view右边缘的距离
*
* @return 返回长度可设置的底部边缘线
*
* @since 5.8
*/
- (UIView *)addBottomLineWithLeft:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-29 11:12:02
*
* 给指定的view(就是self),加一根长度可设置的水平线,以Top为Y方向的基准点
*
* @param top 水平线距离设定view上边缘的距离
* @param left 水平线距离设定view左边缘的距离
* @param right 水平线距离设定view右边缘的距离
*
* @return 返回水平线
*
* @since 5.8
*/
- (UIView *)addHorizontalLineWithTop:(CGFloat)top left:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-29 11:12:48
*
* 给指定的view(就是self),加一根长度可设置的水平线,以Bottom为Y方向的基准点
*
* @param bottom 水平线距离设定view下边缘的距离
* @param left 水平线距离设定view左边缘的距离
* @param right 水平线距离设定view右边缘的距离
*
* @return 返回水平线
*
* @since 5.8
*/
- (UIView *)addHorizontalLineWithBottom:(CGFloat)bottom left:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-29 11:12:48
*
* 给指定的view(就是self),加一根长度可设置的竖直线,以Left为X方向的基准点
*
* @param left 竖直线距离设定view左边缘的距离
* @param top 竖直线距离设定view上边缘的距离
* @param bottom 竖直线距离设定view下边缘的距离
*
* @return 返回竖直线
*
* @since 5.8
*/
- (UIView *)addVerticalLineWithLeft:(CGFloat)left top:(CGFloat)top bottom:(CGFloat)bottom;
/**
* @author licong, 16-12-29 11:12:54
*
* 给指定的view(就是self),加一根长度可设置的竖直线,以Right为X方向的基准点
*
* @param right 竖直线距离设定view右边缘的距离
* @param top 竖直线距离设定view上边缘的距离
* @param bottom 竖直线距离设定view下边缘的距离
*
* @return 返回竖直线
*
* @since 58
*/
- (UIView *)addVerticalLineWithRight:(CGFloat)right top:(CGFloat)top bottom:(CGFloat)bottom;
@end
//
// UIView+LineWithAutolayout.m
// ZhengXing
//
// Created by wangyang on 11/6/14.
// Copyright (c) 2014 Wanmei Creative. All rights reserved.
//
#import "UIView+LineWithAutolayout.h"
#import <Masonry/Masonry.h>
#import "GMConstant.h"
#import "GMTheme.h"
@interface OnePixelLine : UIView
@end
@implementation OnePixelLine
@end
@implementation UIView (LineWithAutolayout)
- (UIView *)addLineWithoutFrame{
UIView *line = [OnePixelLine new];
line.backgroundColor = SEPARATOR_LINE_COLOR;
[self addSubview:line];
return line;
}
- (UIView *)addTopLine
{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(0);
make.right.mas_equalTo(0);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addBottomLine
{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(0);
make.left.mas_equalTo(0);
make.right.mas_equalTo(0);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addCenterHorizontalLineWithLeft:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(0);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addCenterVerticalLineWithTop:(CGFloat)top bottom:(CGFloat)bottom{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.centerX.mas_equalTo(0);
make.bottom.mas_equalTo(bottom);
make.width.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addTopLineWithLeft:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addBottomLineWithLeft:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(0);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addHorizontalLineWithTop:(CGFloat)top left:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addHorizontalLineWithBottom:(CGFloat)bottom left:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(bottom);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addVerticalLineWithLeft:(CGFloat)left top:(CGFloat)top bottom:(CGFloat)bottom{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.left.mas_equalTo(left);
make.bottom.mas_equalTo(bottom);
make.width.offset(ONE_PIXEL);
}];
return line;
}
- (UIView *)addVerticalLineWithRight:(CGFloat)right top:(CGFloat)top bottom:(CGFloat)bottom{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.right.mas_equalTo(right);
make.bottom.mas_equalTo(bottom);
make.width.offset(ONE_PIXEL);
}];
return line;
}
@end
\ No newline at end of file
//
// UIViewController+ChildSwitch.h
// segmentSwitch
//
// Created by wangyang on 5/13/15.
// Copyright (c) 2015 IGIU. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIViewController (ChildControllerSwitch)
@property (nonatomic, strong) IBOutlet UIView *childContainer;
@property (nonatomic, strong) UIViewController *currentController;
/**
* @brief 设置第一个要显示的controller
*
*/
- (void)setFirstController:(UIViewController *)controller;
- (void)setFirstController:(UIViewController *)controller otherController:(NSArray *)otherControllers;
- (void)switchToChildControllerAtIndex:(NSUInteger)index completion:(void (^)(void))completionBlock;
@end
//
// UIViewController+ChildSwitch.m
// segmentSwitch
//
// Created by wangyang on 5/13/15.
// Copyright (c) 2015 IGIU. All rights reserved.
//
#import "UIViewController+ChildControllerSwitch.h"
#import <objc/runtime.h>
@implementation UIViewController (ChildControllerSwitch)
/**
* set方法是为了适应IB,如果纯代码可以不用set方法
*/
- (void)setChildContainer:(UIView *)childContainer{
objc_setAssociatedObject(self, @selector(childContainer), childContainer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)childContainer{
UIView *childContainer = objc_getAssociatedObject(self, _cmd);
if (!childContainer) {
childContainer = [UIView new];
objc_setAssociatedObject(self, _cmd, childContainer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return childContainer;
}
- (void)setCurrentController:(UIViewController *)currentController{
objc_setAssociatedObject(self, NSSelectorFromString(@"currentController"), currentController, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIViewController *)currentController{
return objc_getAssociatedObject(self, NSSelectorFromString(@"currentController"));
}
- (void)setFirstController:(UIViewController *)controller{
controller.view.frame = self.childContainer.bounds;
[self.childContainer addSubview:controller.view];
self.currentController = controller;
[self addChildViewController:controller];
[self.currentController didMoveToParentViewController:self];
}
- (void)setFirstController:(UIViewController *)controller otherController:(NSArray *)otherControllers;{
NSAssert(controller, @"不能设置nil为第一个controller");
NSAssert(self.childContainer.superview, @"self.childContainer must have a superview");
[self setFirstController:controller];
for (UIViewController *other in otherControllers) {
[self addChildViewController:other];
}
}
- (void)switchToChildControllerAtIndex:(NSUInteger)index completion:(void (^)(void))completionBlock
{
UIViewController *to = self.childViewControllers[index];
UIViewController *from = self.currentController;
if (to == from) {
if (completionBlock) {
completionBlock();
}
return;
}
[self.currentController willMoveToParentViewController:nil];
to.view.frame = self.childContainer.bounds;
to.view.alpha = 0;
[self transitionFromViewController:from toViewController:to duration:0.1 options:UIViewAnimationOptionCurveLinear animations:^{
from.view.alpha = 0;
to.view.alpha = 1;
} completion:^(BOOL finished) {
// didMoveToParentViewController必须在transition completion之后
[to didMoveToParentViewController:self];
self.currentController = to;
if (completionBlock) {
completionBlock();
}
}];
}
@end
// The MIT License (MIT)
//
// Copyright (c) 2015-2016 forkingdog ( https://github.com/forkingdog )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#import <UIKit/UIKit.h>
/// "UINavigation+FDFullscreenPopGesture" extends UINavigationController's swipe-
/// to-pop behavior in iOS 7+ by supporting fullscreen pan gesture. Instead of
/// screen edge, you can now swipe from any place on the screen and the onboard
/// interactive pop transition works seamlessly.
///
/// Adding the implementation file of this category to your target will
/// automatically patch UINavigationController with this feature.
@interface UINavigationController (FDFullscreenPopGesture)
/// The gesture recognizer that actually handles interactive pop.
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *fd_fullscreenPopGestureRecognizer;
/// A view controller is able to control navigation bar's appearance by itself,
/// rather than a global way, checking "fd_prefersNavigationBarHidden" property.
/// Default to YES, disable it if you don't want so.
@property (nonatomic, assign) BOOL fd_viewControllerBasedNavigationBarAppearanceEnabled;
@end
/// Allows any view controller to disable interactive pop gesture, which might
/// be necessary when the view controller itself handles pan gesture in some
/// cases.
@interface UIViewController (FDFullscreenPopGesture)
/// Whether the interactive pop gesture is disabled when contained in a navigation
/// stack.
@property (nonatomic, assign) BOOL fd_interactivePopDisabled;
/// Indicate this view controller prefers its navigation bar hidden or not,
/// checked when view controller based navigation bar's appearance is enabled.
/// Default to NO, bars are more likely to show.
@property (nonatomic, assign) BOOL fd_prefersNavigationBarHidden;
/// Max allowed initial distance to left edge when you begin the interactive pop
/// gesture. 0 by default, which means it will ignore this limit.
@property (nonatomic, assign) CGFloat fd_interactivePopMaxAllowedInitialDistanceToLeftEdge;
@end
//
// GMAnnotation.h
// Gengmei
//
// Created by Thierry on 4/25/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface GMAnnotation : NSObject<MKAnnotation>
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
-(id) initWithCoordinate:(CLLocationCoordinate2D) coords;
@end
//
// GMAnnotation.m
// Gengmei
//
// Created by Thierry on 4/25/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMAnnotation.h"
@implementation GMAnnotation
-(id) initWithCoordinate:(CLLocationCoordinate2D) coords
{
if (self = [super init]) {
self.coordinate = coords;
}
return self;
}
@end
//
// GMButton.h
// Gengmei
//
// Created by Thierry on 12/26/14.
// Copyright (c) 2014 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
//见设计稿(UI组件化->组件_按钮.sketch)
typedef NS_ENUM(NSUInteger, GMButtonType) {
GMButtonTypeGreen, //绿色矩形(见左1)
GMButtonTypeGreenRound, //绿色带6px的圆角矩形(见左2)
GMButtonTypeGreenSemicircle, //绿色半圆矩形(见左3)
GMButtonTypeGreenBorder, //绿色边框矩形,只有两种状态(正常、失效,见左4)
GMButtonTypeRed, //红色矩形(见右1)
GMButtonTypeRedRound, //红色色带6px的圆角矩形(见右2)
GMButtonTypeRedSemicircle, //红色半圆矩形(见右3)
GMButtonTypeRedBorder, //红色边框矩形,只有两种状态(正常、失效、见右4)
GMButtonTypeGrayBorderSemicircle, //灰色边框半圆矩形,只有两种状态(正常、失效、见右5)
};
@interface GMButton : UIButton
/**
* @author licong, 16-12-30 17:12:10
*
* button高亮时的背景色
*
* @since 5.8
*/
@property (nonatomic, readonly) UIColor *highlightBackgroundColor;
/**
* @author licong, 16-12-30 17:12:31
*
* button在normal时候的背景色
*
* @since 5.8
*/
@property (nonatomic, readonly) UIColor *normalBackgroundColor;
/**
* @author licong, 16-12-30 17:12:59
*
* button 在选中状态时候的背景色
*
* @since 5.8
*/
@property (nonatomic, readonly) UIColor *selectedBackgroundColor;
/**
* @author licong, 16-12-30 17:12:55
*
* 是否支持Button自适应热区,Apple人机交互指南建议,可点击控件的热区最好是44*44,默认是NO,不支持
*
* @since 5.8
*/
@property (nonatomic, assign) BOOL enableAdaptive;
/**
* @author licong, 16-12-30 17:12:31
*
* 自适应热区宽,默认是 44
*
* @since 5.8
*/
@property (nonatomic, assign) float adaptiveHotAreaWidth;
/**
* @author licong, 16-12-30 17:12:09
*
* 自适应热区高,默认是 44
*
* @since 5.8
*/
@property (nonatomic, assign) float adaptiveHotAreaHeight;
/**
* @author licong, 16-12-30 17:12:30
*
* 初始化方法
*
* @since 5.8
*/
- (void)setup __attribute__((objc_requires_super));
/**
* @author licong, 16-12-30 17:12:46
*
* 创建一个button,并设置好它的title、backgroundColor、size、titleColor
*
* @param title title
* @param bgColor backgroundColor
* @param size 大小
* @param titleColor title标题
*
* @return 返回创建好的button
*
* @since 5.8
*/
+ (instancetype)buttonWithTitle:(nullable NSString *)title
backgroundColor:(nullable UIColor *)bgColor
titleFontSize:(CGFloat)size
titleColor:(nullable UIColor *)titleColor;
/**
* @author licong
*
* UI组件化后自定制Button
*
* @param customType 工厂模式下的button类型
*
* @return 返回创建好的button
*
* @since 6.2.0
*/
+ (instancetype)buttonWithCustomType:(GMButtonType)customType;
/**
* @author licong, 16-12-30 17:12:29
*
* 根据Button的状态设置对应的背景颜色
*
* @param backgroundColor button的背景颜色
* @param state button的controlState
*
* @since 5.8
*/
- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// GMButton.m
// Gengmei
//
// Created by Thierry on 12/26/14.
// Copyright (c) 2014 Wanmeichuangyi. All rights reserved.
//
#import "GMButton.h"
#import "GMFont.h"
#import "GMTheme.h"
#import "GMConstant.h"
@interface GMButton ()
@property (nonatomic, strong) UIColor *highlightBackgroundColor;
@property (nonatomic, strong) UIColor *normalBackgroundColor;
@property (nonatomic, strong) UIColor *selectedBackgroundColor;
@property (nonatomic, strong) UIColor *disableBackgroundColor;
@property (nonatomic, assign) GMButtonType customType;
@property (nonatomic, strong) UIColor *normalBorderColor;
@property (nonatomic, strong) UIColor *disableBorderColor;
@end
@implementation GMButton
#pragma mark - 初始化
-(id)init
{
self = [super init];
if (self) {
[self setup];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)awakeFromNib{
[super awakeFromNib];
[self setup];
}
- (void)setup{
_adaptiveHotAreaWidth = 44.0;
_adaptiveHotAreaHeight = 44.0;
_normalBackgroundColor = [UIColor clearColor];
}
#pragma mark - 实例化方法
+ (instancetype)buttonWithTitle:(NSString *)title
backgroundColor:(UIColor *)bgColor
titleFontSize:(CGFloat)size
titleColor:(UIColor *)titleColor{
GMButton *button = [GMButton buttonWithType:UIButtonTypeCustom];
if (bgColor) {
button.backgroundColor = bgColor;
}
if (title) {
[button setTitle:title forState:UIControlStateNormal];
}
if (size > 0) {
button.titleLabel.font = GMFont(14);
}
if (titleColor) {
[button setTitleColor:titleColor forState:UIControlStateNormal];
}
return button;
}
+ (instancetype)buttonWithCustomType:(GMButtonType)customType{
GMButton *button = [GMButton buttonWithType:UIButtonTypeCustom];
button.clipsToBounds = YES;
button.customType = customType;
[button setTitle:@"按钮" forState:UIControlStateNormal];
switch (customType) {
case GMButtonTypeGreen:
[button setGreenAppearance];
break;
case GMButtonTypeGreenRound:
[button setGreenAppearance];
button.layer.cornerRadius = 6 * ONE_PIXEL;
break;
case GMButtonTypeGreenSemicircle:
[button setGreenAppearance];
break;
case GMButtonTypeGreenBorder:
button.layer.borderWidth = ONE_PIXEL;
button.layer.cornerRadius = 6 * ONE_PIXEL;
button.normalBorderColor = MAIN_VISUAL_COLOR;
button.disableBorderColor = DISABLE_COLOR;
[button setBackgroundColor: [UIColor clearColor] forState:UIControlStateNormal];
[button setTitleColor:MAIN_VISUAL_COLOR forState:UIControlStateNormal];
[button setTitleColor:DISABLE_COLOR forState:UIControlStateDisabled];
button.enabled = YES;
break;
case GMButtonTypeRed:
[button setRedAppearance];
break;
case GMButtonTypeRedRound:
[button setRedAppearance];
button.layer.cornerRadius = 6 * ONE_PIXEL;
break;
case GMButtonTypeRedSemicircle:
[button setRedAppearance];
break;
case GMButtonTypeRedBorder:
button.layer.borderWidth = ONE_PIXEL;
button.layer.cornerRadius = 6 * ONE_PIXEL;
button.normalBorderColor = SECONDARY_VISUAL_COLOR;
button.disableBorderColor = DISABLE_COLOR;
[button setBackgroundColor: [UIColor clearColor] forState:UIControlStateNormal];
[button setTitleColor:SECONDARY_VISUAL_COLOR forState:UIControlStateNormal];
[button setTitleColor:DISABLE_COLOR forState:UIControlStateDisabled];
button.enabled = YES;
break;
case GMButtonTypeGrayBorderSemicircle:
button.layer.borderColor = SEPARATOR_LINE_COLOR.CGColor;
button.layer.borderWidth = ONE_PIXEL;
[button setBackgroundColor: BACKGROUND_COLOR forState:UIControlStateNormal];
[button setBackgroundColor: SEPARATOR_LINE_COLOR forState:UIControlStateHighlighted];
[button setTitleColor:BODY_TEXT_COLOR forState:UIControlStateNormal];
default:
break;
}
return button;
}
//为半圆的设置半径
- (void)layoutSubviews{
[super layoutSubviews];
if (_customType == GMButtonTypeGreenSemicircle || _customType == GMButtonTypeRedSemicircle || _customType == GMButtonTypeGrayBorderSemicircle) {
self.layer.cornerRadius = MIN(self.frame.size.height, self.frame.size.width)/2;
}
}
#pragma mark - Button Appearance
- (void)setGreenAppearance{
[self setTitleColor:WHITE_COLOR forState:UIControlStateNormal];
[self setBackgroundColor:BUTTON_NOMARL_GREEN_COLOR forState:UIControlStateNormal];
[self setBackgroundColor:BUTTON_HIGHLIGHT_GREEN_COLOR forState:UIControlStateHighlighted];
[self setBackgroundColor:BUTTON_DISABLE_COLOR forState:UIControlStateDisabled];
}
- (void)setRedAppearance{
[self setTitleColor:WHITE_COLOR forState:UIControlStateNormal];
[self setBackgroundColor:BUTTON_NOMARL_RED_COLOR forState:UIControlStateNormal];
[self setBackgroundColor:BUTTON_HIGHLIGHT_RED_COLOR forState:UIControlStateHighlighted];
[self setBackgroundColor:BUTTON_DISABLE_COLOR forState:UIControlStateDisabled];
}
#pragma mark - Background Color
- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state{
if (state == UIControlStateNormal) {
_normalBackgroundColor = backgroundColor;
[self setBackgroundColor:_normalBackgroundColor];
}else if (state == UIControlStateHighlighted){
_highlightBackgroundColor = backgroundColor;
}else if (state == UIControlStateSelected){
_selectedBackgroundColor = backgroundColor;
}else if (state == UIControlStateDisabled) {
_disableBackgroundColor = backgroundColor;
}
}
#pragma mark - Setter
- (void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
if (_highlightBackgroundColor && highlighted) {
self.backgroundColor = _highlightBackgroundColor;
}else{
if (self.selected && _selectedBackgroundColor) {
self.backgroundColor = _selectedBackgroundColor;
}else{
self.backgroundColor = _normalBackgroundColor;
}
}
}
- (void)setSelected:(BOOL)selected{
[super setSelected:selected];
if (_selectedBackgroundColor && selected) {
self.backgroundColor = _selectedBackgroundColor;
}else{
self.backgroundColor = _normalBackgroundColor;
}
}
- (void)setBackgroundColor:(UIColor *)backgroundColor{
[super setBackgroundColor:backgroundColor];
// 容错处理,只在为normal状态,才设置_normalBackgroundColor。
// 比如在controller里只调用了setBackgroundColor,为了保证在normal时回复到normal颜色,必须设置好_normalBackgroundColor
if(self.state == UIControlStateNormal){
_normalBackgroundColor = backgroundColor;
}
}
- (void)setEnabled:(BOOL)enabled{
[super setEnabled:enabled];
if (enabled) {
self.backgroundColor = _normalBackgroundColor;
if (_customType == GMButtonTypeGreenBorder || _customType == GMButtonTypeRedBorder) {
self.layer.borderColor = _normalBorderColor.CGColor;
}
}else{
self.backgroundColor = _disableBackgroundColor;
if (_customType == GMButtonTypeGreenBorder || _customType == GMButtonTypeRedBorder) {
self.layer.borderColor = _disableBorderColor.CGColor;
}
}
}
#pragma mark - 支持自适应热区
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
//默认不支持放大热区
if (!_enableAdaptive) {
return [super pointInside:point withEvent:event];
}
CGRect bounds = self.bounds;
//若原热区小于 _adaptiveHotAreaWidth x _adaptiveHotAreaHeight,则放大热区,否则保持原大小不变
CGFloat widthDelta = MAX(_adaptiveHotAreaWidth - bounds.size.width, 0);
CGFloat heightDelta = MAX(_adaptiveHotAreaHeight - bounds.size.height, 0);
bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
return CGRectContainsPoint(bounds, point);
}
@end
//
// GMCollectionView
// Gengmei
//
// Created by Thierry on 1/9/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface GMCollectionView : UICollectionView
@end
//
// GMCollectionView
// Gengmei
//
// Created by Thierry on 1/9/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMCollectionView.h"
@implementation GMCollectionView
@end
//
// GMSimpleCell.h
// Gengmei
// 简单的Collection Cell(图片+文字)
// Created by Thierry on 1/7/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "GMImageView.h"
#import "GMLabel.h"
@interface GMCollectionViewCell : UICollectionViewCell
@property (nonatomic,retain) GMImageView *imageView;
@property (nonatomic,retain) GMLabel *label;
- (void)setup;
@end
//
// GMSimpleCell.m
// Gengmei
//
// Created by Thierry on 1/7/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMCollectionViewCell.h"
#import "GMFont.h"
#import "GMConstant.h"
#import "GMTheme.h"
#define CELL_HEIGHT self.contentView.frame.size.height
#define CELL_WIDTH self.contentView.frame.size.width
@implementation GMCollectionViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)awakeFromNib{
[super awakeFromNib];
[self setup];
}
- (void)setup{
self.clipsToBounds = YES;
_imageView = [[GMImageView alloc] initWithFrame:CGRectMake((CELL_WIDTH-45)/2, 10, 45, 45)];
_label = [[GMLabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_imageView.frame)+6, CELL_WIDTH, 13)];
_label.textColor = HEADLINE_TEXT_COLOR;
_label.font = GMFont(12);
[_label setTextAlignment:NSTextAlignmentCenter];
[self.contentView addSubview:_imageView];
[self.contentView addSubview:_label];
}
@end
//
// GMControl.h
// Gengmei
//
// Created by wangyang on 9/14/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface GMControl : UIControl
/**
* @brief 不需要重写 init 方法,如果代码里调用了 init 方法,SDK 会自动调用 initWithFrame
*
*/
- (void)setup __attribute__((objc_requires_super));
@end
//
// GMControl.m
// Gengmei
//
// Created by wangyang on 9/14/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMControl.h"
@implementation GMControl
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
[self setup];
return self;
}
- (void)setup{
}
@end
//
// GMDatePicker.h
// ZhengXing
//
// Created by Sean Lee on 11/19/14.
// Copyright (c) 2014 Wanmei Creative. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol GMDatePickerDelegate <NSObject>
/**
* @author licong, 16-01-08 15:01:24
*
* 弹出DatePicker
*
* @since 5.8.0
*/
- (void)openPicker;
@end
@interface GMDatePickerView : UIView<UIGestureRecognizerDelegate>
@property (nonatomic, strong) UIView * contentView;
@property (nonatomic, strong) UIDatePicker *picker;
@property (nonatomic, assign) id<GMDatePickerDelegate> delegate;
@property (nonatomic, strong) NSString * leftButtonTitle;
@property (nonatomic, strong) NSString * titleLabelTitle;
@property (nonatomic, copy) void (^ confirmButtonClickBolck) (NSDate * selecteDate);
-(void)show;
-(void)hide;
@end
//
// GMDatePicker.m
// ZhengXing
//
// Created by Sean Lee on 11/19/14.
// Copyright (c) 2014 Wanmei Creative. All rights reserved.
//
#import "GMDatePickerView.h"
#import "GMFont.h"
#import <Masonry/Masonry.h>
#import "GMConstant.h"
#import "GMTheme.h"
#define DATAPICKER_HEIGHT
@interface GMDatePickerView ()
@property (nonatomic,strong)UIButton * leftButton;
@property (nonatomic,strong)UILabel * titleLabel;
@property (nonatomic,strong)UIButton * rightButton;
@end
@implementation GMDatePickerView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithWhite:0 alpha:.6];
self.hidden = YES;
[self createDatePicker];
}
return self;
}
- (void)createDatePicker{
_contentView = [[UIView alloc]initWithFrame:CGRectZero];
_contentView.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.width, self.frame.size.width, 255);
_contentView.backgroundColor = [UIColor whiteColor];
[self addSubview:_contentView];
_picker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 39, [[UIScreen mainScreen] bounds].size.width, 216)];
_picker.backgroundColor = [UIColor whiteColor];
_picker.datePickerMode = UIDatePickerModeDate;
//2037-12-31 23:59:59的时间戳
_picker.maximumDate = [NSDate dateWithTimeIntervalSince1970:2145887999];
[_picker setDate:[NSDate date] animated:NO];
[_picker addTarget:self action:@selector(didPickerSelected:) forControlEvents:UIControlEventValueChanged];
[_contentView addSubview:_picker];
_picker.layer.borderWidth = 1;
_picker.layer.borderColor = SEPARATOR_LINE_COLOR.CGColor;
_leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
_leftButton.tag = 1;
_leftButton.hidden = YES;
[_contentView addSubview:_leftButton];
[_leftButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_contentView.mas_left).with.offset(16);
make.top.equalTo(_contentView.mas_top).offset(4);
}];
[_leftButton.titleLabel setFont:GMFont(16)];
[_leftButton setTitleColor:MAIN_VISUAL_COLOR forState:UIControlStateNormal];
[_leftButton addTarget:self action:@selector(confirmButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
_titleLabel = [[UILabel alloc]init];
_titleLabel.hidden = YES;
_titleLabel.font = GMFont(17);
[_titleLabel setTextColor:[UIColor blackColor]];
[_contentView addSubview:_titleLabel];
[_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(_contentView);
make.top.equalTo(_leftButton.mas_top).with.offset(6);
}];
_rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
_rightButton.tag = 2;
[_contentView addSubview:_rightButton];
[_rightButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(_contentView.mas_right).with.offset(-16);
make.top.equalTo(_contentView.mas_top).offset(4);
}];
[_rightButton setTitleColor:MAIN_VISUAL_COLOR forState:UIControlStateNormal];
[_rightButton setTitle:@"确定" forState:UIControlStateNormal];
[_rightButton.titleLabel setFont:GMFont(16)];
[_rightButton addTarget:self action:@selector(confirmButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
tapGesture.delegate = self;
[self addGestureRecognizer:tapGesture];
}
- (void)setLeftButtonTitle:(NSString *)leftButtonTitle{
_leftButtonTitle= leftButtonTitle;
_leftButton.hidden = NO;
[_leftButton setTitle:leftButtonTitle forState:UIControlStateNormal];
}
- (void)setTitleLabelTitle:(NSString *)titleLabelTitle{
_titleLabelTitle = titleLabelTitle;
_titleLabel.hidden = NO;
_titleLabel.text = titleLabelTitle;
}
- (void)didPickerSelected:(id)sender{
if (self.confirmButtonClickBolck) {
self.confirmButtonClickBolck(_picker.date);
}
}
- (void)confirmButtonClicked:(id)sender{
UIButton * button = (UIButton *)sender;
if (button.tag ==1) {
if (self.confirmButtonClickBolck) {
self.confirmButtonClickBolck(nil);
}
}else if(button.tag == 2){
if (self.confirmButtonClickBolck) {
self.confirmButtonClickBolck(_picker.date);
}
}
[self hide];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
{
CGPoint touch = [gestureRecognizer locationInView:self];
if(!CGRectContainsPoint(_contentView.frame, touch))
{
return YES;
}
return NO;
}
return YES;
}
- (void)tap:(UITapGestureRecognizer *)recognizer
{
if ([self.delegate respondsToSelector:@selector(openPicker)]) {
[self.delegate openPicker];
}
}
-(void)show
{
[_picker setDate:[NSDate date] animated:NO];
[UIView animateWithDuration:0.2 delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.contentView.frame = CGRectMake(0, MAINSCREEN_HEIGHT - 255, MAINSCREEN_WIDTH, self.contentView.frame.size.height);
} completion:^(BOOL finished) {
}];
}
-(void)hide
{
[UIView animateWithDuration:0.2 delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.contentView.frame = CGRectMake(0, MAINSCREEN_HEIGHT, MAINSCREEN_WIDTH, self.contentView.frame.size.height);
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
} completion:^(BOOL finished) {
self.hidden = YES;
self.backgroundColor = [UIColor colorWithWhite:0 alpha:.3];
}];
}
@end
//
// GMEmptyView.h
// Gengmei
//
// Created by Terminator on 15/10/16.
// Copyright © 2015年 Wanmeichuangyi. All rights reserved.
//
#import "GMView.h"
#import "GMImageView.h"
#import "GMLabel.h"
#import "GMButton.h"
@interface GMEmptyView : GMView
@property (nonatomic, strong) GMImageView *imageView;
@property (nonatomic, strong) GMLabel *promoptLabel;
@property (nonatomic, strong) GMButton *actionButton;
@end
//
// GMEmptyView.m
// Gengmei
//
// Created by Terminator on 15/10/16.
// Copyright © 2015年 Wanmeichuangyi. All rights reserved.
//
#import "GMEmptyView.h"
#import "GMFont.h"
#import <Masonry/Masonry.h>
#import "GMConstant.h"
#import "GMTheme.h"
@implementation GMEmptyView
- (void)setup {
[super setup];
_imageView = [[GMImageView alloc] init];
[self addSubview:_imageView];
_promoptLabel = [[GMLabel alloc] init];
_promoptLabel.textAlignment = NSTextAlignmentCenter;
_promoptLabel.font = GMFont(14);
_promoptLabel.textColor = SECONDARY_TEXT_COLOR;
[self addSubview:_promoptLabel];
_actionButton = [[GMButton alloc] init];
_actionButton.titleLabel.font = GMFont(14);
_actionButton.layer.borderWidth = ONE_PIXEL;
_actionButton.layer.borderColor = SECONDARY_TEXT_COLOR.CGColor;
_actionButton.titleLabel.textColor = SECONDARY_TEXT_COLOR;
[_actionButton setTitleColor:SECONDARY_TEXT_COLOR forState:UIControlStateNormal];
[self addSubview:_actionButton];
}
- (void)updateConstraints {
[super updateConstraints];
[_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(122);
make.centerX.mas_equalTo(0);
}];
[_promoptLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(0);
make.top.equalTo(_imageView.mas_bottom).offset(15);
}];
[_actionButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(0);
make.top.equalTo(_promoptLabel.mas_bottom).offset(15);
make.width.mas_equalTo(120);
}];
}
@end
//
// GMHightlightLabel.h
// Gengmei
//
// Created by wangyang on 6/11/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <GMKit/GMLabel.h>
/**
* @brief 设置font,textColor,及GMHightlightLabel特有的lineHeight、hightlightColor以配置要显示的字符串属性
*/
@interface GMHighlightLabel : GMLabel
/**
* @brief 对齐方式
*/
@property (nonatomic, assign) NSTextAlignment aligment;
/**
* @brief 行高
*/
@property (nonatomic, assign) CGFloat lineHeight;
/**
* @brief 默认是 MAIN_VISUL_COLOR
*/
@property (nonatomic, strong) UIColor *hightlightColor;
/**
* @brief 默认是 MAIN_VISUL_COLOR
*/
@property (nonatomic, strong) UIColor *normalColor;
/**
* @brief 带高亮标志的原始字符串
*
*/
@property (nonatomic, copy) NSString *originalHightlightText;
/**
* @author licong, 16-12-30 18:12:58
*
* 创建一个高亮lable
*
* @param color label颜色
* @param font title的font大小
*
* @return 一个高亮lable
*
* @since 5.8
*/
+ (GMHighlightLabel *)hightLabelTextColor:(UIColor *)color andFont:(CGFloat)font;
@end
//
// GMHightlightLabel.m
// Gengmei
//
// Created by wangyang on 6/11/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMHighlightLabel.h"
#import "GMFont.h"
#import "GMConstant.h"
#import "GMTheme.h"
@implementation GMHighlightLabel
- (void)setOriginalHightlightText:(NSString *)originalHightlightText{
_originalHightlightText = originalHightlightText;
if (_originalHightlightText.length == 0) {
self.attributedText = nil;
}
if (!_hightlightColor) {
_hightlightColor = MAIN_VISUAL_COLOR;
}
if (!_normalColor) {
_normalColor = BODY_TEXT_COLOR;
}
NSMutableAttributedString *attString = [self parseString:_originalHightlightText];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = _lineHeight;
style.lineBreakMode = NSLineBreakByTruncatingTail;
style.alignment = _aligment;
// 如果有高亮,attString不为空,那只加一个NSParagraphStyleAttributeName属性
if (self.lineHeight > 0 && attString.length > 0) {
[attString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, attString.length)];
}
// 如果没有走到正则里面,说明没有需要高亮的内容,设置普通颜色就好
else if (attString.length == 0) {
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:_originalHightlightText attributes:@{NSFontAttributeName : self.font, NSForegroundColorAttributeName:_normalColor, NSParagraphStyleAttributeName:style}];
[attString appendAttributedString:subString];
}
self.attributedText = attString;
}
- (NSMutableAttributedString *)parseString:(NSString *)originalString{
NSError *error;
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:@"([\\w\\W]*)<ems>([\\w\\W]+)<\\/ems>([\\w\\W]*)" options:0 error:&error];
if (error) {
self.attributedText = nil;
}
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[expression enumerateMatchesInString:originalString options:0 range:NSMakeRange(0, originalString.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
// 根据NSTextCheckingResult的rangeAtIndex方法文档,result至少会有一个range,这个range是匹配它自身全部的,所以正则匹配的其它range是从1开始的
// <ems></ems>将string分隔为string1, string2, string3,分别对应前中后
NSString *string1 = [originalString substringWithRange:[result rangeAtIndex:1]];
NSAttributedString *attrString1 = [self parseString:string1];
if (attrString1.length > 0) {
[attString appendAttributedString:attrString1];
}else{
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string1 attributes:@{NSFontAttributeName : self.font, NSForegroundColorAttributeName:_normalColor}];
[attString appendAttributedString:subString];
}
NSString *string2 = [originalString substringWithRange:[result rangeAtIndex:2]];
NSAttributedString *attrString2 = [self parseString:string2];
if (attrString2.length > 0) {
[attString appendAttributedString:attrString2];
}else{
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string2 attributes:@{NSFontAttributeName : self.font, NSForegroundColorAttributeName:_hightlightColor}];
[attString appendAttributedString:subString];
}
NSString *string3 = [originalString substringWithRange:[result rangeAtIndex:3]];
NSAttributedString *attrString3 = [self parseString:string3];
if (attrString3.length > 0) {
[attString appendAttributedString:attrString3];
}else{
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string3 attributes:@{NSFontAttributeName : self.font, NSForegroundColorAttributeName:_normalColor}];
[attString appendAttributedString:subString];
}
}];
return attString;
}
+ (GMHighlightLabel *)hightLabelTextColor:(UIColor *)color andFont:(CGFloat)font {
GMHighlightLabel *label = [[GMHighlightLabel alloc] init];
label.backgroundColor = [UIColor whiteColor];
label.textColor = color;
label.font = GMFont(font);
label.hightlightColor = MAIN_VISUAL_COLOR;
return label;
}
@end
//
// GMHorizontalLayoutButton.h
// Gengmei
//
// Created by wangyang on 8/17/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMButton.h"
/**
* @author licong, 15-09-27 17:09:12
*
* Button同时存在图片和文字时候的排列样式
*
* @since 5.2.0
*/
typedef NS_ENUM(NSInteger, GMButtonImageArrangeType){
//图片居左,文字居右
GMButtonImageArrangeLeftType = 1,
//文字居左,图片居右
GMButtonImageArrangeRightType = 2,
};
__deprecated_msg("使用GMKit-Swift库中的AllLayoutButton.swift代替,会在9月份被删除掉")
@interface GMHorizontalLayoutButton : GMButton
/**
* @brief 设置button image 和 title的间距
*/
@property (nonatomic, assign) CGFloat imageAndTitleSpace;
@property (nonatomic, assign) GMButtonImageArrangeType imageArrangeType;
@end
//
// GMHorizontalLayoutButton.m
// Gengmei
//
// Created by wangyang on 8/17/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMHorizontalLayoutButton.h"
#import "GMFont.h"
#import "NSString+GM.h"
@interface GMHorizontalLayoutButton ()
@property(nonatomic, assign)CGFloat finalSpace;
@end
@implementation GMHorizontalLayoutButton
- (void)setImageArrangeType:(GMButtonImageArrangeType)imageArrangeType{
_imageArrangeType = imageArrangeType;
[self arrangeByImageArrangeType:imageArrangeType];
}
- (void)arrangeByImageArrangeType:(GMButtonImageArrangeType)imageArrangeType{
if (imageArrangeType == GMButtonImageArrangeLeftType) {
_finalSpace = self.imageAndTitleSpace/2.0;
self.titleEdgeInsets = UIEdgeInsetsMake(0, _finalSpace, 0, 0);
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, _finalSpace);
}else{
CGFloat titleWidth = [self.currentTitle sizeWithFont:self.titleLabel.font boundSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)].width;
_finalSpace = self.imageAndTitleSpace * 2 + titleWidth;
CGFloat imageWidth = self.currentImage.size.width * [UIScreen mainScreen].scale;
self.titleEdgeInsets = UIEdgeInsetsMake(0, -(imageWidth + self.imageAndTitleSpace * 2), 0, 0);
self.imageEdgeInsets = UIEdgeInsetsMake(0, _finalSpace, 0, 0);
}
}
- (void)updateConstraints{
[self arrangeByImageArrangeType:self.imageArrangeType];
[super updateConstraints];
}
- (CGSize)intrinsicContentSize{
CGSize size = [super intrinsicContentSize];
size.width += self.imageAndTitleSpace;
return size;
}
@end
//
// GMImageView.h
// Gengmei
//
// Created by Thierry on 2/12/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface GMImageView : UIImageView
/**
* @author licong, 16-12-31 15:12:46
*
* 将图片裁剪成圆形
*
* @since 5.8
*/
- (void)makeRoundImage;
/**
* @author licong, 16-12-31 12:12:36
*
* 获取图片,并渐现效果
*
* @param urlString 图片源路径
* @param placeHolder 默认的placeHolder
*
* @since 5.8
*/
- (void)setImageWithUrlString:(NSString *)urlString placeHolder:(NSString *)placeHolder;
@end
//
// GMImageView.m
// Gengmei
//
// Created by Thierry on 2/12/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMImageView.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import "UIView+Layout.h"
#import "GMConstant.h"
#import "GMTheme.h"
@implementation GMImageView
- (void)makeRoundImage{
CGFloat cornerRadius = MIN(self.width, self.height)/2;
self.layer.cornerRadius = cornerRadius;
self.layer.masksToBounds = YES;
self.layer.borderWidth = 0.5;
self.layer.borderColor = SEPARATOR_LINE_COLOR.CGColor;
}
- (void)setImageWithUrlString:(NSString *)urlString placeHolder:(NSString *)placeHolder{
NSURL *url = [NSURL URLWithString:urlString];
if (placeHolder!=nil && ![placeHolder isEqualToString:@""]) {
[self setImage:[UIImage imageNamed:placeHolder]];
[self sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:placeHolder] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (cacheType==SDImageCacheTypeNone) {
[GMImageView fadeInTransition:self];
}
}];
}else{
[self sd_setImageWithURL:url completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (cacheType==SDImageCacheTypeNone) {
[GMImageView fadeInTransition:self];
}
}];
}
}
+ (void)fadeInTransition:(UIImageView *)view{
CATransition *transtion = [CATransition animation];
transtion.duration = 0.5;
[transtion setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[transtion setType:kCATransitionFade];
[transtion setSubtype:kCATransitionFromRight];
[view.layer addAnimation:transtion forKey:@"transtionKey"];
}
@end
//
// GMInfiniteScrollView.h
//
//
// Created by wangyang on 10/12/15.
// Copyright (c) 2015年 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "GMView.h"
@class GMInfiniteScrollView;
@protocol GMInfinitelViewDelegate <NSObject>
@optional
- (void)infiniteScrollView:(GMInfiniteScrollView *)infiniteScrollView didSelectIndex:(NSInteger)index;
@end
@interface GMInfiniteScrollView : GMView <UIScrollViewDelegate>{
UIScrollView *_scrollView;
NSInteger _currentPage;
}
@property (nonatomic, assign) id<GMInfinitelViewDelegate> delegate;
/**
* @author licong, 16-12-31 18:12:50
*
* 轮播图片的填充模式
*
* @since 5.8
*/
@property (nonatomic, assign) UIViewContentMode imageContentMode;
// 存放所有需要滚动的图片URL NSString
/**
* @author licong, 16-12-31 17:12:26
*
* 需要轮播的数据源
*
* @since 5.8
*/
@property (nonatomic, strong) NSArray *imageArray;
/**
* @author licong, 16-12-31 18:12:11
*
* 轮播的时间间隔
*
* @since 5.8
*/
@property (nonatomic, assign) NSTimeInterval timeInterval;
/**
* @author licong, 16-12-31 18:12:42
*
* pageControl
*
* @since 5.8
*/
@property (nonatomic, strong) UIPageControl *pageControl;
/**
* @author licong, 16-12-31 18:12:09
*
* 是否允许手动滚动
*
* @since 5.8
*/
@property (nonatomic, assign) BOOL enableRolling;
/**
* @author licong, 16-12-31 18:12:34
*
* 开始轮播
*
* @since 5.8
*/
- (void)startRolling;
/**
* @author licong, 16-12-31 18:12:48
*
* 停止轮播
*
* @since 5.8
*/
- (void)stopRolling;
@end
This diff is collapsed.
//
// GMLabel.h
// Gengmei
//
// Created by Thierry on 12/26/14.
// Copyright (c) 2014 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface GMLabel : UILabel
typedef NS_ENUM(NSInteger, GMLabelVerticalAlignment){
GMLabelVerticalAlignmentTop = 0, // 垂直方向顶部对齐
GMLabelVerticalAlignmentMiddle, // 垂直方向中间对齐
GMLabelVerticalAlignmentBottom, // 垂直方向底部对齐
};
/**
* @brief 垂直方向对齐。默认是 GMLabelVerticalAlignmentMiddle。因为有这个属性,所以需要重写 drawTextInRect
*/
@property (nonatomic,assign) GMLabelVerticalAlignment verticalAlignment;
/**
* @brief 文字与label边框的padding。因为有这个方法,所以重写了 intrinsicContentSize
*/
@property (nonatomic, assign) UIEdgeInsets paddingEdge;
/**
* @author licong, 16-12-30 17:12:50
*
* 创建一个UILabel
*
* @param TextColor 色值
* @param fontSize font大小
*
* @return 一个新的UILabel
*
* @since 5.8
*/
+ (GMLabel *)labelWithTextColor:(UIColor *)color fontSize:(CGFloat)fontSize;
/**
* @brief 创建一个UILabel
*
* @param textAlignment 对齐方式
* @param backgroundColor 背景颜色
* @param textColor 文字颜色
* @param fontSize 字号
*/
+ (GMLabel *)labelWithTextAlignment:(NSTextAlignment)textAlignment backgroundColor:(UIColor*)backgroundColor textColor:(UIColor*)textColor fontSize:(CGFloat )fontSize;
/**
* @brief 设置label属性
*
* @param textAlignment 对齐方式
* @param backgroundColor 背景颜色
* @param textColor 文字颜色
* @param fontSize 字号
*/
- (void)setTextAlignment:(NSTextAlignment)textAlignment backgroundColor:(UIColor*)backgroundColor textColor:(UIColor*)textColor fontSize:(CGFloat )fontSize;
@end
This diff is collapsed.
//
// GMLoadingView.h
// loadingAnimation
//
// Created by wangyang on 12/23/14.
// Copyright (c) 2014 WY. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, GMLoadingViewType) {
GMLoadingViewTypeGray,
GMLoadingViewTypeGreenLarge,
GMLoadingViewTypeGreenSmall
};
@interface GMLoadingView : UIView
+ (instancetype)loadingViewWithType:(GMLoadingViewType)type;
- (void)begingAnimation;
- (void)endAnimation;
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//
// GMPlaceholderTextContainer.h
// Gengmei
//
// Created by wangyang on 16/1/5.
// Copyright © 2016年 Wanmeichuangyi. All rights reserved.
//
#import "GMView.h"
#import "GMLabel.h"
/**
* @author wangyang, 16-01-05 14:01:02
*
* @brief 提供一个有placeholderLable的textView。因为直接在UITextView上添加subview可能会导致crash(这应该是SDK的bug),在高版本sdk不会crash,所以只能提供这样一个view,分别包含UITextVie和Label
* @since 5.8.0
*/
@interface GMPlaceholderTextContainer : GMView
@property (nonatomic, strong) GMLabel *placeholderLabel;
@property (nonatomic, strong) UITextView *textView;
@property (nonatomic, assign) CGPoint placeholderOrigin;
// 等于 textView.text
@property (nonatomic, copy) NSString *text;
// 等于 placeholderLabel.text
@property (nonatomic, copy) NSString *placeholder;
// 等于 textView.resignFirstResponder
- (BOOL)resignFirstResponder;
// 等于 textView.becomeFirstResponder
- (BOOL)becomeFirstResponder;
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment