Contenu connexe Similaire à Swipe 2011 - iOS Gems (20) Swipe 2011 - iOS Gems1. iOS Gems
Some jewels for your glory box
Kevin O’Neill
Delivery Manager – Mobile
REA Group
twitter: @kevinoneill
This is not a con dential session — please stream, blog, tweet and take pictures :)
2. Roadmap
• Enhancing NSArray
• View size and layout
• Simple gestures handling
• Closing thoughts
6. It’s verbose
- (NSIndexSet *)indexesOfObjectsWithOptions:
(NSEnumerationOptions)opts passingTest:(BOOL
(^)(id obj, NSUInteger idx, BOOL *stop))
predicate
7. Difficult to combine
- (NSIndexSet *)indexesOfObjectsAtIndexes:
(NSIndexSet *)indexes options:
(NSEnumerationOptions)opts passingTest:(BOOL
(^)(id obj, NSUInteger idx, BOOL
*stop))predicate;
8. We Can Do Better
• Enumeration
• Filtering
• Transformation
15. EG
NSMutableSet *uniqueNames = [NSMutableSet
set];
[names each: ^ (id name) {
[uniqueNames addObject:name];
}];
16. OR
[[view subviews] eachWithIndex:^ (id subview,
NSUInteger position) {
CGRect cell_frame =
CGRectMake(subview_width * position,
0,
requested_subview_size.width,
requested_subview_size.height);
22. Filter
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
[[names filter:^BOOL(id name) {
return [name length] < 5;
}] each:^(id name) {
NSLog(@"%@", name);
}];
"Kevin"
"Aaron"
"Maddie"
24. Pick
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
[[names pick:^BOOL(id name) {
return [name length] < 5;
}] each:^(id name) {
NSLog(@"%@", name);
}];
"Sue"
"Jack"
26. First
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
NSLog(@"%@", [names first:^BOOL(id name) {
return [name length] < 5;
}]);
"Sue"
28. Last
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
NSLog(@"%@", [names last:^BOOL(id name) {
return [name length] < 5;
}]);
"Jack"
30. Transformation
- (NSArray *)map:(id (^)(id item))block;
- (id)reduce:(id (^)(id current, id item))block
initial:(id)initial;
- (NSArray *)intersperse:(id (^) (void))separator;
32. Map
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
[[names map:^id(id name) {
return [NSNumber numberWithInteger:
[name length]];
}] each:^(id length) {
NSLog(@"%@", length);
}];
"5"
"3"
"5"
…
34. Reduce
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
NSLog(@"%@",
[names reduce:^id(id current, id item) {
NSInteger result = [current integerValue]
+ [item length];
return [NSNumber numberWithInteger:result];
} initial:[NSNumber numberWithInteger:0]]);
"23"
36. Intersperse
NSArray *names = [NSArray arrayWithObjects:
@"Kevin", @"Sue", @"Aaron",
@"Jack", @"Maddie", nil];
[[names intersperse:^id(id current, id next) {
return [current length] > [next length]
? @">" : @"<";
}] each:^(id item) {
NSLog(@"%@", item);
}];
"Kevin"
">"
"Sue"
"<"
…
43. Two methods are key
- (void)layoutSubviews;
- (CGSize)sizeThatFits:(CGSize)size;
47. - (void)layoutSubviews;
• Does nothing by default
• Used to position subviews
• Called when the layout is dirty
• Don’t call it manually– I’ve seen to
many times
• Don’t resize self – I’ve seen to many
times
48. - (CGSize)sizeThatFits:
(CGSize)size;
• Returns current size by default
• Return ‘best’ size to fit given size
• Doesn’t resize the view
• Don’t resize the view – I’ve seen to
many times
• Don’t layout view – I’ve seen to many
times
51. EG
- (CGSize)sizeThatFits:(CGSize)size;
{
float width = size.width;
float height = [[[self subviews] reduce: ^ id (id current, id item) {
CGSize item_size = [item sizeThatFits:CGSizeMake(width, 0.)];
return [NSNumber numberWithFloat:
ceilf([current floatValue] +
(item_size.height + [self spacingForSubview:item]))];
} initial:[NSNumber numberWithFloat:0.]] floatValue];
CGSize result = CGSizeMake(width, height);
return result;
}
52. And
- (void)layoutSubviews;
{
float width = [self width];
__block StackedView *block_self = self;
[[self subviews] reduce: ^ id (id current, id item) {
CGSize item_size = [item sizeThatFits:CGSizeMake(width, 0.)];
[item setFrame:
CGRectMake(0,
[current floatValue] + [block_self spacingForSubview:item],
item_size.width,
item_size.height)];
return [NSNumber numberWithFloat:ceilf([item bottom])];
} initial:[NSNumber numberWithFloat:0.]];
}
62. EG
- (void)cancelRequest
{
[self displayCancelMessage];
}
UITapGestureRecognizer *tapRecognizer =
[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(cancelRequest)];
80. Useful Bits
Open source libraries used
https://github.com/kevinoneill/Useful-Bits
https://github.com/kevinoneill/Useful-Swipe
https://github.com/domesticcatsoftware/DCIntrospect
Questions?