天天看點

iOS快速開發必備

http://segmentfault.com/a/1190000003520629?utm_source=Weibo&utm_medium=shareLink&utm_campaign=social

前言

github:https://github.com/koknine (終于改成以前的了)

目前移動網際網路行業太火爆,移動端的需求日益增長,很多開發人員每天都應對着各種需求,作為一名iOS開發人員,對于需求來說,我們要做到的是實作,而對于自己來說,我們需要做到的是寫出高品質的代碼。

于是,全球的大神們開源了很多高品質、可複用的代碼,給予了芸芸衆生(心中一萬個感謝)。例如我們常用的 AFNetworking,SDWebImage,Masonry 等等,這些第三方庫内容強大,性能很高,為大家帶來了很多福利。

在開發過程當中,适當合理的使用這些第三方庫能幫我們節省很多的時間。這些優秀的第三方庫就如同教科書一樣,當我們深入挖掘的時候,才能獲得更高的提升。

好了,吹了半天牛,我們現在到底要做什麼呢?其實我想說的是,合理的使用第三方庫能大大的提升開發效率,也許我們自己研究做動畫弄半天,還不如開源動畫好用,這樣的情況很多時候我們是不得不承認的。與其與之較勁,不如我們先使用它們的架構,然後再做深入探究,這樣方能更好的掌握。

網上很多好的整理,我這裡引用一下:剛剛線上部落格,裡面有很多整理好的内容,非常好的幹貨。感謝原作者的内容,其中有一個整理的是iOS開發好用的 category,能幫我們節省很多精力,接下來我就先一一分析github上面這些category,翻譯其中重要的内容。

聲明:本人翻譯并不能做到百分之百準确,内容如果有誤,歡迎下方評論指導,謝謝!

UIImageView_FaceAwareFill

簡介

位址:https://github.com/Julioacarrettoni/UIImageView_FaceAwareFill

This category applies Aspect Fill content mode to an image and if faces are detected it centers them instead of centering the image just by its geometrical center.

這個 category 使用了 Aspect Fill 的模式來顯示圖檔并且當人臉被檢測到時,它會就以臉部中心替代圖檔的集合中心。

使用

pch 檔案中直接導入

設定完一個

UIImageView

的屬性以後直接

然後就完了。。。。。

個人評價

看到沒有,大神的提供的方法就是如此狂拽炫酷叼霸天,就是如此的簡單。

NSRegularEx+ObjCRegex

簡介

位址:https://github.com/bendytree/Objective-C-RegEx-Categories

This project simplifies regular expressions in Objective-C and Swift.

這個猛,直接把

objective-c

swift

裡面的正規表達式給整合了。

這是一組對比

// Without this library
NSString* string = @"I have 2 dogs.";
NSRegularExpression *regex = [NSRegularExpression regular ExpressionWithPattern:@"\\d+" options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:string options: range:NSMakeRange(, [string length])];
BOOL isMatch = match != nil;

// With this library
BOOL isMatch = [@"I have 2 dogs." isMatch:RX(@"\\d+")];
           

使用

安裝過程就不贅述了,要麼是cocoapods,要麼直接拖進去。

老規矩,在 pch 檔案中添加:

#ifdef __OBJC__
    /* ...other references... */
    #import "RegExCategories.h"
#endif
           

當然,你的工程需要開啟

ARC

Swift

支援

這個就需要一個橋接檔案,百度即可,

Swift

引用 OC 的三方都是需要一個橋接檔案。

後面的教程就不翻譯了,直接去看代碼吧,少年。

個人評價

還在為正規表達式而糾結嗎?還在調試正規表達式問題嗎?沒錯,走過路過不要錯誤,這裡有你想要的一切。

NSObject+AutoCoding

簡介

位址:https://github.com/nicklockwood/AutoCoding

這個是一個

NSObject

的 category,提供了對

NSCoding

NSCopying

的自動支援。這意味着你不要寫

initWithCoder:

encodeWithCoder:

了,這個直接承包了。

當然,怎麼用還是要看自己的,它并不能讀懂你的思維。還有舉個例子,你應該避免使用結構體因為它并不遵循

NSCoding

協定,而是通過

NSValue

支援很多版本

支援

ARC

MRC

線程安全

使用

直接把

AutoCoding.h

AutoCoding.m

拖進工程。

其實自己寫歸檔和反歸檔也沒有那麼複雜,這裡就不做詳細介紹了。

個人評價

這個其實還好,不過其中的機制很不錯,值得一看,後面有時間我再翻譯。

UILabel-ContentSize

簡介

來源:https://github.com/mergesort/UILabel-ContentSize

使用

通過傳入的字元串來改變

UILabel

Size

直接把

.h

.m

檔案導入工程吧。

個人評價

正如同作者所說的,總是會忘記操作細節,不如直接寫成 category。

UIViewController-Swizzled

簡介

來源:https://github.com/RuiAAPeres/UIViewController-Swizzled

這個能幫你管理你的應用。當你正在做複雜的行為以及剛接手工程的時候這個會變得特别好用。使用這個 category 能看到你現在所在的

UIViewController

,還有展示你進入的層次。

使用

老規矩,要麼直接拖入,要麼用

cocoapods

需要導傳入連結接庫:

libobjc.dylib
           

然後導入頭檔案:

AppDelegate

中,你需要在方法

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

方法裡面加入

SWIZZ_IT 

開啟。如果因為什麼原因你想要停止,隻需要添加

UN_SWIZZ_IT 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    SWIZZ_IT;
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self.window makeKeyAndVisible];

    // Your code...

    return YES;
}
           

然後就能看到輸出:

2013-09-09 18:58:42.360 Testing[25399:c07] -> UINavigationController
2013-09-09 18:58:42.361 Testing[25399:c07] ---> RPViewController
2013-09-09 18:59:55.072 Testing[25399:c07] -----> RPSecondViewController
2013-09-09 18:59:57.367 Testing[25399:c07] -------> RPThirdViewController
2013-09-09 18:59:58.801 Testing[25399:c07] -----> RPSecondViewController
2013-09-09 19:00:00.282 Testing[25399:c07] -------> RPThirdViewController
2013-09-09 19:00:01.906 Testing[25399:c07] ---------> RPViewController
2013-09-09 19:00:03.515 Testing[25399:c07] -------> RPThirdViewController
2013-09-09 19:00:04.267 Testing[25399:c07] -----> RPSecondViewController
2013-09-09 19:00:05.041 Testing[25399:c07] ---> RPViewController
2013-09-09 19:00:07.193 Testing[25399:c07] -----> RPSecondViewController
2013-09-09 19:00:08.312 Testing[25399:c07] -------> RPThirdViewController
2013-09-09 19:00:09.396 Testing[25399:c07] ---------> RPViewController
2013-09-09 19:00:10.183 Testing[25399:c07] -----------> RPSecondViewController
2013-09-09 19:00:10.905 Testing[25399:c07] -------------> RPThirdViewController
2013-09-09 19:00:12.141 Testing[25399:c07] ---------------> RPViewController
2013-09-09 19:00:13.156 Testing[25399:c07] -----------------> RPSecondViewController                

個人評價

當你剛接手一個新的項目的時候,無數個檔案。

這是什麼鬼?程式怎麼運作的?那個類是幹嘛用的?為什麼運作到了這裡,還有,檔案怎麼找?要瘋掉了。。。

有了此神器,天黑都不怕,一步一步是爪牙,是魔鬼的步伐,程式的運作一清二楚,簡直出門旅行,居家必備之良藥。

你值得擁有!

NSDate-Escort

簡介

來源:https://github.com/azu/NSDate-Escort

加強

NSDate

使用

/**
 Returns the calendarIdentifier of calendars that is used by this library for date calculation.
 @see AZ_setDefaultCalendarIdentifier: for more details.
 */
+ (NSString *)AZ_defaultCalendarIdentifier;
/**
 Sets the calendarIdentifier of calendars that is used by this library for date calculation.
 You can specify any calendarIdentifiers predefined by NSLocale. If you provide nil, the library uses
 [NSCalendar currentCalendar]. Default value is nil.

 You can't provide individual calendars for individual date objects. If you need to perform such
 complicated date calculations, you should rather create calendars on your own.
 */
+ (void)AZ_setDefaultCalendarIdentifier:(NSString *)calendarIdentifier;

#pragma mark - Relative dates from the current date

- (BOOL)isYesterday;
- (BOOL)isSameWeekAsDate:(NSDate *) aDate;
- (BOOL)isThisWeek;
- (BOOL)isNextWeek;
- (BOOL)isLastWeek;
- (BOOL)isSameMonthAsDate:(NSDate *) aDate;
- (BOOL)isThisMonth;
- (BOOL)isSameYearAsDate:(NSDate *) aDate;
- (BOOL)isThisYear;
- (BOOL)isNextYear;
- (BOOL)isLastYear;
- (BOOL)isEarlierThanDate:(NSDate *) aDate;
- (BOOL)isLaterThanDate:(NSDate *) aDate;
- (BOOL)isEarlierThanOrEqualDate:(NSDate *) aDate;
- (BOOL)isLaterThanOrEqualDate:(NSDate *) aDate;
- (BOOL)isInFuture;
- (BOOL)isInPast;
#pragma mark - Date roles
- (BOOL)isTypicallyWorkday;
- (BOOL)isTypicallyWeekend;
#pragma mark - Adjusting dates
- (NSDate *)dateByAddingYears:(NSInteger) dYears;
- (NSDate *)dateBySubtractingYears:(NSInteger) dYears;
- (NSDate *)dateByAddingMonths:(NSInteger) dMonths;
- (NSDate *)dateBySubtractingMonths:(NSInteger) dMonths;
- (NSDate *)dateByAddingDays:(NSInteger) dDays;
- (NSDate *)dateBySubtractingDays:(NSInteger) dDays;
- (NSDate *)dateByAddingHours:(NSInteger) dHours;
- (NSDate *)dateBySubtractingHours:(NSInteger) dHours;
- (NSDate *)dateByAddingMinutes:(NSInteger) dMinutes;
- (NSDate *)dateBySubtractingMinutes:(NSInteger) dMinutes;
- (NSDate *)dateAtStartOfDay;
- (NSDate *)dateAtEndOfDay;
- (NSDate *)dateAtStartOfWeek;
- (NSDate *)dateAtEndOfWeek;
- (NSDate *)dateAtStartOfMonth;
- (NSDate *)dateAtEndOfMonth;
- (NSDate *)dateAtStartOfYear;
- (NSDate *)dateAtEndOfYear;
#pragma mark - Retrieving intervals
- (NSInteger)minutesAfterDate:(NSDate *) aDate;
- (NSInteger)minutesBeforeDate:(NSDate *) aDate;
- (NSInteger)hoursAfterDate:(NSDate *) aDate;
- (NSInteger)hoursBeforeDate:(NSDate *) aDate;
- (NSInteger)daysAfterDate:(NSDate *) aDate;
- (NSInteger)daysBeforeDate:(NSDate *) aDate;
- (NSInteger)monthsAfterDate:(NSDate *) aDate;
- (NSInteger)monthsBeforeDate:(NSDate *) aDate;
/**
* return distance days
*/
- (NSInteger)distanceInDaysToDate:(NSDate *) aDate;
#pragma mark - Decomposing dates
/**
* return nearest hour
*/
@property(readonly) NSInteger nearestHour;
@property(readonly) NSInteger hour;
@property(readonly) NSInteger minute;
@property(readonly) NSInteger seconds;
@property(readonly) NSInteger day;
@property(readonly) NSInteger month;
@property(readonly) NSInteger week;
//  in the Gregorian calendar, n is 7 and Sunday is represented by 1.
@property(readonly) NSInteger weekday;
@property(readonly) NSInteger firstDayOfWeekday;
@property(readonly) NSInteger lastDayOfWeekday;
// e.g. 2nd Tuesday of the month == 2
@property(readonly) NSInteger nthWeekday;
           

個人評價

無需多說,看方法名字就知道有什麼作用了,回想起之前處理時間的日子。。。多麼痛的領悟,果然那句話很對:磨刀不誤砍柴工。

UIView+Toast

簡介

來源:https://github.com/scalessec/Toast

使用

注意導入

QuartzCore

圖檔已經執行個體代碼源位址都有,就幾個參數

  • makeToast

     要顯示的内容
  • duration

     持續時間
  • position

     放置的位置
  • title

     标題
  • image

     放置的圖檔
  • makeToastActivity

     顯示 toast

個人評價

簡單好用,清晰明了。

NYXImagesKit

簡介

來源:https://github.com/Nyx0uf/NYXImagesKit

NYXImagesKit是一個重組了多個有用的UIImage categories的iOS項目,可對圖像/圖檔進行多個處理,比如篩選、模糊、優化、蒙版、調整大小、旋轉以及儲存等等。同時還提供了一個UIImageView子類從URL異步加載圖檔,并在下載下傳完畢時展示圖檔。

使用

首先打開

NYXImagesKit.xcodeproj

然後運作庫,之後把庫和頭檔案導入到你的工程裡面,最後要連結以下的架構:

  • Accelerate
  • AssetsLibrary
  • ImageIO
  • MobileCoreServices
  • QuartzCore
  • CoreImage

UIImage+Blurring

模糊效果

UIImage+Masking

蒙闆效果

UIImage* masked = [myImage maskWithImage:[UIImage imageNamed:@"mask.png"]];
           

UIImage+Resizing

重置尺寸

  1. 上左
  2. 上中
  3. 上右
  4. 下左
  5. 下中
  6. 下右
  7. 左中
  8. 右中
  9. 中間
UIImage* cropped = [myImage cropToSize:(CGSize){width, height} usingMode:NYXCropModeCenter];
           

NYXCropMode

是一個枚舉類型,能在頭檔案裡面找到,表示不同的類型

Scaling

縮放

你有兩種方法來縮放圖檔,這兩種方法都能保持原圖檔比例

UIImage* scaled1 = [myImage scaleByFactor:f];
UIImage* scaled2 = [myImage scaleToFitSize:(CGSize){width, height}];
           

UIImage+Rotating

旋轉

UIImage* rotated1 = [myImage rotateInDegrees:f];
UIImage* rotated2 = [myImage rotateInRadians:M_PI_2];
UIImage* flipped1 = [myImage verticalFlip];
UIImage* flipped2 = [myImage horizontalFlip];
           

UIImage+Reflection

重構圖檔

UIImage+Enhancing

提升

[myImage autoEnhance];
[myImage redEyeCorrection];
           

UIImage+Saving

儲存類型

這個能把圖檔存到一個位址或者相冊,支援五種類型

  1. BMP
  2. GIF
  3. JPG
  4. PNG
  5. TIFF

要用這個就必須導入

ImageIO.framework

MobileCoreServices.framework

還有

AssertsLibrary.framework

[myImage saveToURL:url type:NYXImageTypeJPEG backgroundFillColor:nil];
[myImage saveToPath:path type:NYXImageTypeTIFF backgroundFillColor:[UIColor yellowColor]];
[myImage saveToPhotosAlbum];                

NYXProgressiveImageView

這個是繼承

UIImageView

的一個類,能異步加載圖檔和緩存。

當然,我們可以使用

SDWebImage

個人評價

這個針對于圖檔處理,很好很強大。

MJPopupViewController

簡介

來源:https://github.com/martinjuhasz/MJPopupViewController

這個是給

UIViewController

提供過渡效果的。

使用

Source

目錄下的檔案夾拖入工程,然後導入

QuartzCore.framework

引入檔案

簡單添加

如果要消失

在執行個體工程中可以看到更多的使用方法。

個人評價

一個非常簡單容易使用的過渡效果,有需求的時候可以使用。

UIColor+Colours

簡介

來源:https://github.com/bennyguitar/Colours

UIColor

提供更多顔色支援

使用

cocoapods

安裝,或者拖入檔案

顔色過多,就不一一列舉了。

RGBA

通過數組可以取出

UIColor

的四個參數,都是

NSNumber

類型,記得他們都是0-1的數,不是0-255

NSArray *colorArray = [[UIColor seafoamColor] rgbaArray];
UIColor *newColor = [UIColor colorFromRGBAArray:colorArray];
           

字典也能取到值

  • kColoursRGBA_R
  • kColoursRGBA_G
  • kColoursRGBA_B
  • kColoursRGBA_A
NSDictionary *colorDict = [[UIColor seafoamColor] rgbaDictionary];
UIColor *newColor = [UIColor colorFromRGBADictionary:colorDict];

// You can also get a single component like so:
NSNumber *r = colorDict[kColoursRGBA_R];
           

後面還有很多方法,不一一列舉了。

個人評價

實際開發中,一般 UI 設計出來各種顔色,位置都确定了,是以不好說這個用的多不多。

NSDate+Helper

簡介

來源:https://github.com/billymeltdown/nsdate-helper

這也是一個擴充

NSDate

的 category

使用

使用友善,

stringForDisplayFromDate

能非常便捷的顯示出很多資訊。

NSString *displayString = [NSDate stringForDisplayFromDate:date];
           

這能顯示出很多資訊

  • ‘3:42 AM’ – 如果時間是在今天半夜
  • ‘Tuesday’ – 如果時間是在這個星期
  • ‘Mar 1’ – 如果日期是在今年
  • ‘Mar 1, 2008’ – else ;-)

另外的方法能顯示幾天之前這樣的資訊

NSDate *date = [NSDate date];
  [date daysAgo]; // provides an NSComponent-based NSUInteger describing days ago.
  [date daysAgoAgainstMidnight]; // better version of daysAgo, works off midnight (hat-tip: "sburlot":http://github.com/sburlot)
  [date stringDaysAgo]; // 'Today', 'Yesterday', or 'N days ago'.
           

構造

date formatters

很糾結?缺少

to_s(:db)

?我也是,

NSDate (Helper)

有些靜态方法能夠在兩者之間轉換,而且能支援資料庫的時間戳。

NSDate *date = [NSDate dateFromString:@"2009-03-01 12:15:23"];
NSString *dbDateString = [NSDate stringFromDate:date]; // returns '2009-03-01 12:15:23'
           

還有

個人評價

這個也不錯,更多功能可以在

.h

檔案裡面找,命名很規範。

ObjectiveSugar

簡介

來源:https://github.com/supermarin/ObjectiveSugar

文法糖功能

使用

使用

cocoapods

,然後導入頭檔案

#import <ObjectiveSugar/ObjectiveSugar.h>

NSNumber

[@ times:^{
    NSLog(@"Hello!");
}];
// Hello!
// Hello!
// Hello!

[@ timesWithIndex:^(NSUInteger index) {
    NSLog(@"Another version with number: %d", index);
}];
// Another version with number: 0
// Another version with number: 1
// Another version with number: 2


[@ upto: do:^(NSInteger numbah) {
    NSLog(@"Current number.. %d", numbah);
}];
// Current number.. 1
// Current number.. 2
// Current number.. 3
// Current number.. 4

[@ downto: do:^(NSInteger numbah) {
    NSLog(@"Current number.. %d", numbah);
}];
// Current number.. 7
// Current number.. 6
// Current number.. 5
// Current number.. 4

NSDate *firstOfDecember = [NSDate date]; // let's pretend it's 1st of December

NSDate *firstOfNovember = [@days since:firstOfDecember];
// 2012-11-01 00:00:00 +0000

NSDate *christmas = [@days until:newYearsDay];
// 2012-12-25 00:00:00 +0000

NSDate *future = @days.fromNow;
// 2012-12-25 20:49:05 +0000

NSDate *past = @month.ago;
// 2012-11-01 20:50:28 +00:00
           

NSArray / NSSet

// All of these methods return a modified copy of the array.
// They're not modifying the source array.

NSArray *cars = @[@"Testarossa", @"F50", @"F458 Italia"]; // or NSSet

[cars each:^(id object) {
    NSLog(@"Car: %@", object);
}];
// Car: Testarossa
// Car: F50
// Car: F458 Italia

[cars eachWithIndex:^(id object, NSUInteger index) {
    NSLog(@"Car: %@ index: %i", object, index);
}];
// Car: Testarossa index: 0
// Car: F50 index: 1
// Car: F458 Italia index: 2

[cars each:^(id object) {
    NSLog(@"Car: %@", object);
} options:NSEnumerationReverse];
// Car: F458 Italia
// Car: F50
// Car: Testarossa

[cars eachWithIndex:^(id object, NSUInteger index) {
    NSLog(@"Car: %@ index: %i", object, index);
} options:NSEnumerationReverse];
// Car: F458 Italia index: 2
// Car: F50 index: 1
// Car: Testarossa index: 0

[cars map:^(NSString* car) {
    return car.lowercaseString;
}];
// testarossa, f50, f458 italia

// Or, a more common example:
[cars map:^(NSString* carName) {
    return [[Car alloc] initWithName:carName];
}];
// array of Car objects

NSArray *mixedData = @[ @, @"Objective Sugar!", @"Github", @, @"5"];

[mixedData select:^BOOL(id object) {
  return ([object class] == [NSString class]);
}];
// Objective Sugar, Github, 5

[mixedData reject:^BOOL(id object) {
    return ([object class] == [NSString class]);
}];
// 1, 4

NSArray *numbers = @[ @, @, @, @ ];
[numbers sort];
// 1, 2, 5, 7

cars.sample
// 458 Italia
cars.sample
// F50
           

NSArray

only

NSArray *numbers = @[@, @, @, @, @, @];

// index from 2 to 4
numbers[@"2..4"];
// [@3, @4, @5]

// index from 2 to 4 (excluded)
numbers[@"2...4"];
// [@3, @4]

// With NSRange location: 2, length: 4
numbers[@"2,4"];
// [@3, @4, @5, @6]

NSValue *range = [NSValue valueWithRange:NSMakeRange(, )];
numbers[range];
// [@3, @4, @5, @6]

[numbers reverse];
// [@6, @5, @4, @3, @2, @1]


NSArray *fruits = @[ @"banana", @"mango", @"apple", @"pear" ];

[fruits includes:@"apple"];
// YES

[fruits take:];
// banana, mango, apple

[fruits takeWhile:^BOOL(id fruit) {
    return ![fruit isEqualToString:@"apple"];
}];
// banana, mango

NSArray *nestedArray = @[ @[ @, @, @ ], @[ @, @, @, @[ @, @ ] ], @, @ ];
[nestedArray flatten];
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

NSArray *abc = @[ @"a", @"b", @"c" ];
[abc join];
// abc

[abc join:@"-"];
// a-b-c

NSArray *mixedData = @[ @, @"Objective Sugar!", @"Github", @, @"5"];

[mixedData detect:^BOOL(id object) {
    return ([object class] == [NSString class]);
}];
// Objective Sugar



// TODO: Make a better / simpler example of this
NSArray *landlockedCountries = @[ @"Bolivia", @"Paraguay", @"Austria", @"Switzerland", @"Hungary" ];
NSArray *europeanCountries = @[ @"France", @"Germany", @"Austria", @"Spain", @"Hungary", @"Poland", @"Switzerland" ];


[landlockedCountries intersectionWithArray:europeanCountries];
// landlockedEuropeanCountries = Austria, Switzerland, Hungary

[landlockedCountries unionWithArray:europeanCountries];
// landlockedOrEuropean = Bolivia, Paraguay, Austria, Switzerland, Hungary, France, Germany, Spain, Poland

[landlockedCountries relativeComplement:europeanCountries];
// nonEuropeanLandlockedCountries = Bolivia, Paraguay

[europeanCountries relativeComplement:landlockedCountries];
// notLandlockedEuropeanCountries = France, Germany, Spain, Poland

[landlockedCountries symmetricDifference:europeanCountries];
// uniqueCountries = Bolivia, Paraguay, France, Germany, Spain, Poland
           

NSMutableArray

NSMutableArray *people = @[ @"Alice", @"Benjamin", @"Christopher" ];

[people push:@"Daniel"]; // Alice, Benjamin, Christopher, Daniel

[people pop]; // Daniel
// people = Alice, Benjamin, Christopher

[people pop:]; // Benjamin, Christopher
// people = Alice

[people concat:@[ @"Evan", @"Frank", @"Gavin" ]];
// people = Alice, Evan, Frank, Gavin

[people keepIf:^BOOL(id object) {
    return [object characterAtIndex:] == 'E';
}];
// people = Evan
           

NSDictionary

NSDictionary *dict = @{ @"one" : @, @"two" : @, @"three" : @ };

[dict each:^(id key, id value){
    NSLog(@"Key: %@, Value: %@", key, value);
}];
// Key: one, Value: 1
// Key: two, Value: 2
// Key: three, Value: 3

[dict eachKey:^(id key) {
    NSLog(@"Key: %@", key);
}];
// Key: one
// Key: two
// Key: three

[dict eachValue:^(id value) {
    NSLog(@"Value: %@", value);
}];
// Value: 1
// Value: 2
// Value: 3

NSDictionary *errors = @{
    @"username" : @[ @"already taken" ],
    @"password" : @[ @"is too short (minimum is 8 characters)", @"not complex enough" ],
    @"email" : @[ @"can't be blank" ];
};

[errors map:^(id attribute, id reasons) {
    return NSStringWithFormat(@"%@ %@", attribute, [reasons join:@", "]);
}];
// username already taken
// password is too short (minimum is 8 characters), not complex enough
// email can't be blank

[errors hasKey:@"email"]
// true
[errors hasKey:@"Alcatraz"]
// false
           

NSString

NSString *sentence = NSStringWithFormat(@"This is a text-with-argument %@", @);
// This is a text-with-argument 1234

[sentence split];
// array = this, is, a, text-with-argument, 1234

[sentence split:@"-"]
// array = this is a text, with, argument 1234

[sentence containsString:@"this is a"];
// YES
           

C

unless(_messages) {
    // The body is only executed if the condition is false
    _messages = [self initializeMessages];
}

int iterations = ;
until(iterations == ) {
    // The body is executed until the condition is false
    //          
    printf("%d ", iterations);
    iterations--;
}
printf("\n");

iterations = ;
do {
    // The body is executed at least once until the condition is false
    // Will print: Executed!
    printf("Executed!\n");
} until(true);
           

個人評價

這是什麼黑科技,簡直改變 OC 文法,簡化更多文法,簡直停不下來。

Kiwi

簡介

來源:https://github.com/kiwi-bdd/Kiwi

Kiwi的作用是用來過來更友善的測試程式,可讀性更高。

使用

詳細需要看文檔。

個人評價

又是一個黑科技,用的時候再檢視文檔吧。

ViewUtils

簡介

來源:https://github.com/nicklockwood/ViewUtils

目的

擴充

UIView

的 category,有幾個方面:

  • 載入

    Nib

    - 不需要

    UIViewController

    就能載入視圖
  • 布局 - 能獨立設定位置或者寬/高
  • 搜尋 - 檢索子視圖,通過類,tag 或者正規表達式
  • 響應者 - 找到一個 view 的第一響應者

線程安全

這個隻能在主線程使用

使用

把兩個檔案拖入工程

方法封裝了系統的

UIView

,很多都是非常實用且增加了安全性能。

還能單獨修改

frame

的值。

個人評價

封裝

UIView

的通用功能,安全性得到提高,還能單獨修改

frame

,增加了很多便利。

NSDate-TimeAgo

簡介

來源:https://github.com/kevinlawler/NSDate-TimeAgo

可以顯示目前時間是多久以前,不過這個已經并入了另一個庫裡面

使用

導入

#import "NSDate+TimeAgo.h"

NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:];
NSString *ago = [date timeAgo];
NSLog(@"Output is: \"%@\"", ago);
-- :: Proj[:] Output is: "41 years ago"
           

還有兩種方法

  • dateTimeAgo - 傳回

    {value} {unit} ago 

    這種格式
  • dateTimeUntilNow - 傳回

    昨天/今早/上個星期/這個月

    ,沒有上面的精确但是更自然。

個人評價

如果隻需要很簡單的功能,這個就能滿足,如果需要對時間更強大處理

通路:https://github.com/MatthewYork/DateTools

iOS-FontAwesome

簡介

來源:https://github.com/alexdrone/ios-fontawesome

添加字型,還有圖檔

使用

首先,在工程裡面必須有

FontAwesome.ttf

,而且在

plist

檔案中的

UIAppFonts

必須包換一個

String item

名字叫

FontAwesome.ttf

然後再導入

NSString+FontAwesome

UILabel *label = [...]
label.font = [UIFont fontWithName:kFontAwesomeFamilyName size:];
           

還能使用枚舉

label.text = [NSString fontAwesomeIconStringForEnum:FAGithub];
           

當然,最重要還是檢視文檔,裡面提供各種字型。

個人評價

确實很不錯,很多種類型的字型,還有圖檔的,總之很給力。

NSObject-AutoDescription

簡介

來源:https://github.com/djmadcat/NSObject-AutoDescription

增加對

NSArray

NSDictionary

還有

NSSet

的描述支援

使用

#import "NAUser.h"
#import "NSObject+AutoDescription.h"

@implementation NAUser

- (NSString *)description
{
    return [self autoDescription];
}

@end
           

個人評價

小而美,有需求的話可以用下。

CGRectPositioning

簡介

來源:https://github.com/mvx24/CGRectPositioning

這個是個宏檔案

可以對

CGRect

很友善的處理

使用

看名字就能知道了,把

CGRectPositioning.h

導入工程,裡面全是宏

個人評價

代碼布局的時候,使用這個就能很友善

總結

先從學習使用開始,到研究分析如何實作,才是大智慧。

繼續閱讀