SlideShare una empresa de Scribd logo
1 de 82
Descargar para leer sin conexión
What I’ve learned when
                     developing
                  BlockAlertViews
                            Gustavo Ambrozio
                             360iDev 2012



Tuesday, September 11, 12
About me
                    • Developing professionally since age of 15




Tuesday, September 11, 12
About me
                    • Developing professionally since age of 15
                    • For iOS since the official SDK came out




Tuesday, September 11, 12
About me
                    • Developing professionally since age of 15
                    • For iOS since the official SDK came out
                    • Did some apps and contracts as an
                            independent developer in Brazil




Tuesday, September 11, 12
About me
                    • Developing professionally since age of 15
                    • For iOS since the official SDK came out
                    • Did some apps and contracts as an
                            independent developer in Brazil
                    • Writter for raywenderlich.com


Tuesday, September 11, 12
About me
                    • Developing professionally since age of 15
                    • For iOS since the official SDK came out
                    • Did some apps and contracts as an
                            independent developer in Brazil
                    • Writter for raywenderlich.com
                    • Hired by PocketGems to code games in SF

Tuesday, September 11, 12
About me
                    • Developing professionally since age of 15
                    • For iOS since the official SDK came out
                    • Did some apps and contracts as an
                            independent developer in Brazil
                    • Writter for raywenderlich.com
                    • Hired by PocketGems to code games in SF
                    • Hate engligh prepositions
Tuesday, September 11, 12
What’s BlockAlertView




Tuesday, September 11, 12
What’s BlockAlertView




Tuesday, September 11, 12
What’s BlockAlertView




Tuesday, September 11, 12
My love and hate story with
                                    UIAlertView
                    •       (apparently) Easy to use   •   Delegates

                                                       •   Switches

                                                       •   Tags

                                                       •   Constants




Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>


                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to”
                                                message:@”Send message using:”
                                                delegate:self
                                        cancelButtonTitle:@”Cancel”
                                        otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil];
                          view.tag = kSendAlertView;
                          [view show];
                          [view release];
                       }




Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>


                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to”
                                                message:@”Send message using:”
                                                delegate:self
                                        cancelButtonTitle:@”Cancel”
                                        otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil];
                          view.tag = kSendAlertView;
                          [view show];
                          [view release];
                       }




Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>


                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to”
                                                message:@”Send message using:”
                                                delegate:self
                                        cancelButtonTitle:@”Cancel”
                                        otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil];
                          view.tag = kSendAlertView;
                          [view show];
                          [view release];
                       }




Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>


                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to”
                                                message:@”Send message using:”
                                                delegate:self
                                        cancelButtonTitle:@”Cancel”
                                        otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil];
                          view.tag = kSendAlertView;
                          [view show];
                          [view release];
                       }




Tuesday, September 11, 12
- (void)alertView:(UIAlertView *)alertView
                 clickedButtonAtIndex:(NSInteger)buttonIndex
              {
                        switch (alertView.tag)
                        {
                             case kRemoveConfirmAlertView:
                                  if (buttonIndex == 1)
                                        [self removeItem];
                                  break;

                            case kSendAlertView:
                            {
                                 switch (buttonIndex)
                                 {
                                      case 0:     // Cancel
                                          break;
                                      case 1:      // Twitter
                                          [self sendWith:kTwitter];
                                          break;
                                      case 2:       // Facebook
                                          [self sendWith:kFacebook];
                                          break;
                                      case 3:      // email
                                          MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                          view.mailComposeDelegate = self;
                                          [self.navigationController presentModalViewController:view animated:YES];
                                          break;
                                 }
                            }
                            break;
                        }
              }


Tuesday, September 11, 12
- (void)alertView:(UIAlertView *)alertView
                 clickedButtonAtIndex:(NSInteger)buttonIndex
              {
                        switch (alertView.tag)
                        {
                             case kRemoveConfirmAlertView:
                                  if (buttonIndex == 1)
                                        [self removeItem];
                                  break;

                            case kSendAlertView:
                            {
                                 switch (buttonIndex)
                                 {
                                      case 0:     // Cancel
                                          break;
                                      case 1:      // Twitter
                                          [self sendWith:kTwitter];
                                          break;
                                      case 2:       // Facebook
                                          [self sendWith:kFacebook];
                                          break;
                                      case 3:      // email
                                          MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                          view.mailComposeDelegate = self;
                                          [self.navigationController presentModalViewController:view animated:YES];
                                          break;
                                 }
                            }
                            break;
                        }
              }


Tuesday, September 11, 12
- (void)alertView:(UIAlertView *)alertView
                 clickedButtonAtIndex:(NSInteger)buttonIndex
              {
                        switch (alertView.tag)
                        {
                             case kRemoveConfirmAlertView:
                                  if (buttonIndex == 1)
                                        [self removeItem];
                                  break;

                            case kSendAlertView:
                            {
                                 switch (buttonIndex)
                                 {
                                      case 0:     // Cancel
                                          break;
                                      case 1:      // Twitter
                                          [self sendWith:kTwitter];
                                          break;
                                      case 2:       // Facebook
                                          [self sendWith:kFacebook];
                                          break;
                                      case 3:      // email
                                          MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                          view.mailComposeDelegate = self;
                                          [self.navigationController presentModalViewController:view animated:YES];
                                          break;
                                 }
                            }
                            break;
                        }
              }


Tuesday, September 11, 12
- (void)alertView:(UIAlertView *)alertView
                 clickedButtonAtIndex:(NSInteger)buttonIndex
              {
                        switch (alertView.tag)
                        {
                             case kRemoveConfirmAlertView:
                                  if (buttonIndex == 1)
                                        [self removeItem];
                                  break;

                            case kSendAlertView:
                            {
                                 switch (buttonIndex)
                                 {
                                      case 0:     // Cancel
                                          break;
                                      case 1:      // Twitter
                                          [self sendWith:kTwitter];
                                          break;
                                      case 2:       // Facebook
                                          [self sendWith:kFacebook];
                                          break;
                                      case 3:      // email
                                          MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                          view.mailComposeDelegate = self;
                                          [self.navigationController presentModalViewController:view animated:YES];
                                          break;
                                 }
                            }
                            break;
                        }
              }


Tuesday, September 11, 12
- (void)alertView:(UIAlertView *)alertView
                 clickedButtonAtIndex:(NSInteger)buttonIndex
              {
                        switch (alertView.tag)
                        {
                             case kRemoveConfirmAlertView:
                                  if (buttonIndex == 1)
                                        [self removeItem];
                                  break;

                            case kSendAlertView:
                            {
                                 switch (buttonIndex)
                                 {
                                      case 0:     // Cancel
                                          break;
                                      case 1:      // Twitter
                                          [self sendWith:kTwitter];
                                          break;
                                      case 2:       // Facebook
                                          [self sendWith:kFacebook];
                                          break;
                                      case 3:      // email
                                          MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                          view.mailComposeDelegate = self;
                                          [self.navigationController presentModalViewController:view animated:YES];
                                          break;
                                 }
                            }
                            break;
                        }
              }


Tuesday, September 11, 12
- (void)alertView:(UIAlertView *)alertView
                 clickedButtonAtIndex:(NSInteger)buttonIndex
              {
                        switch (alertView.tag)
                        {
                             case kRemoveConfirmAlertView:
                                  if (buttonIndex == 1)
                                        [self removeItem];
                                  break;

                            case kSendAlertView:
                            {
                                 switch (buttonIndex)
                                 {
                                      case 0:     // Cancel
                                          break;
                                      case 1:      // Twitter
                                          [self sendWith:kTwitter];
                                          break;
                                      case 2:       // Facebook
                                          [self sendWith:kFacebook];
                                          break;
                                      case 3:      // email
                                          MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                          view.mailComposeDelegate = self;
                                          [self.navigationController presentModalViewController:view animated:YES];
                                          break;
                                 }
                            }
                            break;
                        }
              }


Tuesday, September 11, 12
How blocks ended my
                          hatred
                    • PSFoundation (https://github.com/steipete/
                            PSFoundation/tree/master/Utils)

                    • Peter Steinberger



Tuesday, September 11, 12
How blocks ended my
                          hatred
                    • PSFoundation (https://github.com/steipete/
                            PSFoundation/tree/master/Utils)

                    • Peter Steinberger
                    • PSAlertView e PSActionSheet


Tuesday, September 11, 12
How blocks ended my
                          hatred
                    • PSFoundation (https://github.com/steipete/
                            PSFoundation/tree/master/Utils)

                    • Peter Steinberger
                    • PSAlertView e PSActionSheet
                    • Renamed to BlockAlertView and
                            BlockActionSheet


Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>

                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to”
                                                 message:@”Send message using:”];
                          [view setCancelButtonWithTitle:@”Cancel” block:nil];
                          [view addButtonWithTitle:@”Twitter”, block:^{
                             [self sendWith:kTwitter];
                          }];
                          [view addButtonWithTitle:@”Facebook”, block:^{
                             [self sendWith:kFacebook];
                          }];
                          [view addButtonWithTitle:@”Email”, block:^{
                             MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                              view.mailComposeDelegate = self;
                                              [self.navigationController presentModalViewController:view animated:YES];
                            }];
                            view .tag = kSendAlertView;
                            [view show];
                       }

Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>

                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to”
                                                 message:@”Send message using:”];
                          [view setCancelButtonWithTitle:@”Cancel” block:nil];
                          [view addButtonWithTitle:@”Twitter”, block:^{
                             [self sendWith:kTwitter];
                          }];
                          [view addButtonWithTitle:@”Facebook”, block:^{
                             [self sendWith:kFacebook];
                          }];
                          [view addButtonWithTitle:@”Email”, block:^{
                             MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                              view.mailComposeDelegate = self;
                                              [self.navigationController presentModalViewController:view animated:YES];
                            }];
                            view .tag = kSendAlertView;
                            [view show];
                       }

Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>

                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to”
                                                 message:@”Send message using:”];
                          [view setCancelButtonWithTitle:@”Cancel” block:nil];
                          [view addButtonWithTitle:@”Twitter”, block:^{
                             [self sendWith:kTwitter];
                          }];
                          [view addButtonWithTitle:@”Facebook”, block:^{
                             [self sendWith:kFacebook];
                          }];
                          [view addButtonWithTitle:@”Email”, block:^{
                             MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                              view.mailComposeDelegate = self;
                                              [self.navigationController presentModalViewController:view animated:YES];
                            }];
                            view .tag = kSendAlertView;
                            [view show];
                       }

Tuesday, September 11, 12
@interface MyViewController : UIViewController <UIAlertViewDelegate>

                       #define kRemoveConfirmAlertView 1
                       #define kSendAlertView         2
                       #define kLogoutConfirmAlertView 3

                       - (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to”
                                                 message:@”Send message using:”];
                          [view setCancelButtonWithTitle:@”Cancel” block:nil];
                          [view addButtonWithTitle:@”Twitter”, block:^{
                             [self sendWith:kTwitter];
                          }];
                          [view addButtonWithTitle:@”Facebook”, block:^{
                             [self sendWith:kFacebook];
                          }];
                          [view addButtonWithTitle:@”Email”, block:^{
                             MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                              view.mailComposeDelegate = self;
                                              [self.navigationController presentModalViewController:view animated:YES];
                            }];
                            view .tag = kSendAlertView;
                            [view show];
                       }

Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view addButtonWithTitle:@”Email”, block:^{
                              MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                               view.mailComposeDelegate = self;
                                               [self.navigationController presentModalViewController:view animated:YES];
                            }];

                            [view show];
                       }


Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view addButtonWithTitle:@”Email”, block:^{
                              MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init];
                                               view.mailComposeDelegate = self;
                                               [self.navigationController presentModalViewController:view animated:YES];
                            }];

                            [view show];
                       }


Tuesday, September 11, 12
Lesson number 1

                    1. Use blocks instead of delegates (almost) all
                       the time




Tuesday, September 11, 12
Lesson number 1

                    1. Use blocks instead of delegates (almost) all
                       the time
                            • Exception: When the block can retain
                              something that can be deallocated before
                              que block call gets made
                              (NSURLConnections for example)



Tuesday, September 11, 12
How to do it
                    1. Subclass the original class and have it conform with it’s
                       delegate.
                    2. Create typedefs for all blocks
                    3. Create @property for all blocks with (copy)
                    4. Implement all init methods and set self as delegate.
                    5. Implement all delegates, create ivars for all and call them
                       if not nil.




Tuesday, September 11, 12
ARC compatibility
                    •       Simple:
                            #if ! __has_feature(objc_arc)
                            #error This file must be compiled with ARC. Please add -fobjc-arc
                            to the compiler flags of this file.
                            #endif


                    •       Better:
                            Use Nick Lockwood’s ARC Helper .h file:
                            https://gist.github.com/1563325




Tuesday, September 11, 12
Improving AVAudioPlayer
                       #import <Foundation/Foundation.h>
                       #import <AVFoundation/AVFoundation.h>
                       #import "ARCHelper.h"

                       typedef void (^AudioPlayerDidFinishPlayingBlock)(BOOL);
                       typedef void (^AudioPlayerDecodeErrorDidOccurBlock)(NSError *);
                       typedef void (^AudioPlayerBeginInterruptionBlock)();
                       typedef void (^AudioPlayerEndInterruptionBlock)(NSUInteger);

                       @interface BlockAudioPlayer : AVAudioPlayer <AVAudioPlayerDelegate>

                       @property (nonatomic, copy) AudioPlayerDidFinishPlayingBlock audioPlayerDidFinishPlayingBlock;
                       @property (nonatomic, copy) AudioPlayerDecodeErrorDidOccurBlock
                       audioPlayerDecodeErrorDidOccurBlock;
                       @property (nonatomic, copy) AudioPlayerBeginInterruptionBlock audioPlayerBeginInterruptionBlock;
                       @property (nonatomic, copy) AudioPlayerEndInterruptionBlock audioPlayerEndInterruptionBlock;

                       @end




Tuesday, September 11, 12
Improving AVAudioPlayer
                       - (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError
                       {
                           self = [super initWithContentsOfURL:url error:outError];
                           if (self)
                           {
                               self.delegate = self;
                           }

                            return self;
                       }

                       #pragma mark - AVAudioPlayerDelegate

                       - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
                       {
                          if (audioPlayerDidFinishPlayingBlock)
                              audioPlayerDidFinishPlayingBlock(flag);
                       }



                     https://github.com/gpambrozio/BlockAudioPlayer
                 Zachary Waldowski’s https://github.com/zwaldowski/BlocksKit

Tuesday, September 11, 12
Hate comes back with
                         a new face




Tuesday, September 11, 12
Hate comes back with
                         a new face




Tuesday, September 11, 12
Hate comes back with
                         a new face




Tuesday, September 11, 12
A vision on how to end
                        this hatred




Tuesday, September 11, 12
A vision on how to end
                        this hatred




Tuesday, September 11, 12
A vision on how to end
                        this hatred




Tuesday, September 11, 12
A vision on how to end
                        this hatred




Tuesday, September 11, 12
Striking hatred with code




Tuesday, September 11, 12
Striking hatred with code




Tuesday, September 11, 12
Striking hatred with code


                      UIWindow

                      UView

                              UILabel



                            UIButton




Tuesday, September 11, 12
Striking hatred with code


                      UIWindow

                      UView

                              UILabel



                            UIButton




Tuesday, September 11, 12
Striking hatred with code


                      UIWindow

                      UView

                              UILabel



                            UIButton




Tuesday, September 11, 12
Lesson number 2

                    2. UIWindow is an unkown obscure class
                       that’s very rarely used (and with very poor
                       documentation) but that might solve some
                       tricky UI problems. Use with care.




Tuesday, September 11, 12
UIWindow basics
                    • No hierarchy. UIWindow are ordered using
                      their windowLevel:
                     • UIWindowLevelNormal
                     • UIWIndowLevelAlert
                     • UIWindowLevelStatusBar
                    • If on the same level, ordered by creation
                      time, last on top.
                    • makeKeyAndVisible can push it to the top,
                            but still respecting windowLevel.


Tuesday, September 11, 12
Key Window
                    •       From the docs: “...window which is currently receiving
                            keyboard events and other non touch-related events.
                            Whereas touch events are delivered to the window in
                            which the touch occurred, events that do not have an
                            associated coordinate value are delivered to the key
                            window of your application. Only one window at a time
                            may be key."

                    •       When you create a UIWindow and call makeKeyWindow,
                            don’t just call resignKeyWindow. Save the previous
                            keyWindow and call makeKeyWindow on it when you’re
                            done.




Tuesday, September 11, 12
Destroying hate




Tuesday, September 11, 12
Lessons number 3 and 4

                    3. Open your mind to other libraries and
                       don’t assume you need to do it the Apple
                       way




Tuesday, September 11, 12
Lessons number 3 and 4

                    3. Open your mind to other libraries and
                       don’t assume you need to do it the Apple
                       way

                    4. Don’t be lazy. It’s fun to implement
                       something from scratch.



Tuesday, September 11, 12
Spreading the love
                    •       BlockAlertView and BlockActionSheets are
                            open source

                    •       github.com/gpambrozio/BlockAlertsAnd-
                            ActionSheets




Tuesday, September 11, 12
Spreading the love
                    •       BlockAlertView and BlockActionSheets are
                            open source

                    •       github.com/gpambrozio/BlockAlertsAnd-
                            ActionSheets

                    •       blog.codecropper.com/2012/01/replicating-
                            tweetbot-alerts-and-action-sheets/




Tuesday, September 11, 12
Spreading the love
                    •       BlockAlertView and BlockActionSheets are
                            open source

                    •       github.com/gpambrozio/BlockAlertsAnd-
                            ActionSheets

                    •       blog.codecropper.com/2012/01/replicating-
                            tweetbot-alerts-and-action-sheets/

                    •       Improvements to UIAlertView and
                            UIActionSheet

Tuesday, September 11, 12
Spreading the love

                    • Import 6 files, 3 .h and 3 .m




Tuesday, September 11, 12
Spreading the love

                    • Import 6 files, 3 .h and 3 .m
                    • Copy 1 .h file with UI attributes




Tuesday, September 11, 12
Spreading the love

                    • Import 6 files, 3 .h and 3 .m
                    • Copy 1 .h file with UI attributes
                    • Copy PNG assets or create your own


Tuesday, September 11, 12
Spreading the love

                    • Import 6 files, 3 .h and 3 .m
                    • Copy 1 .h file with UI attributes
                    • Copy PNG assets or create your own
                    • Change UI (optional)

Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view setDestructiveButtonWithTitle:@”Delete”, block:^{
                               [self removeItem];
                            }];

                            [view show];
                       }



Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view setDestructiveButtonWithTitle:@”Delete”, block:^{
                               [self removeItem];
                            }];

                            [view show];
                       }



Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view setDestructiveButtonWithTitle:@”Delete”, block:^{
                               [self removeItem];
                            }];

                            [view show];
                       }



Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view setDestructiveButtonWithTitle:@”Delete”, block:^{
                               [self removeItem];
                            }];

                            [view show];
                       }



Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view setDestructiveButtonWithTitle:@”Delete”, block:^{
                               [self removeItem];
                            }];

                            [view show];
                       }



Tuesday, September 11, 12
- (IBAction)sendItem:(id)sender
                       {
                          BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to”
                                                message:@”Send message using:”];

                            [view setCancelButtonWithTitle:@”Cancel” block:nil];

                            [view addButtonWithTitle:@”Twitter”, block:^{
                               [self sendWith:kTwitter];
                            }];

                            [view addButtonWithTitle:@”Facebook”, block:^{
                               [self sendWith:kFacebook];
                            }];

                            [view setDestructiveButtonWithTitle:@”Delete”, block:^{
                               [self removeItem];
                            }];

                            [view show];
                       }



Tuesday, September 11, 12
Spreading the love




Tuesday, September 11, 12
Spreading the love




Tuesday, September 11, 12
Advanced love
                    • Background and buttons and simple PNGs




Tuesday, September 11, 12
Advanced love
                    • It’s only an UIView....

                                       [BlockBackground
                                        sharedInstance]



                                         UIView




Tuesday, September 11, 12
Advanced love
                    • BlockTextPromptAlertView




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Animated love




Tuesday, September 11, 12
Lesson number 5

                    5. Opening your source is good: Improves
                       your karma, your reputation and your
                       source code.




Tuesday, September 11, 12
Gustavo Ambrozio

                    • @gpambrozio
                    • blog.codecropper.com
                    • github.com/gpambrozio
                    • linkedin.com/in/gustavoambrozio

Tuesday, September 11, 12
We’re hiring



                            2 apps in top 25 grossing apps




Tuesday, September 11, 12

Más contenido relacionado

Destacado

Why Smart Employees Underperform
Why Smart Employees UnderperformWhy Smart Employees Underperform
Why Smart Employees Underperformmother55
 
Fracas escolar? La solució inesperada del gènere i la coeducació
Fracas escolar? La solució inesperada del gènere i la coeducacióFracas escolar? La solució inesperada del gènere i la coeducació
Fracas escolar? La solució inesperada del gènere i la coeducacióEdu Torres
 
Wp3 refresh pgh
Wp3 refresh pghWp3 refresh pgh
Wp3 refresh pghMrDirby
 
As aves que frequentam a nossa escola
As aves que frequentam a nossa escolaAs aves que frequentam a nossa escola
As aves que frequentam a nossa escolajpog
 

Destacado (7)

Bo 31 05-2013-30 (2)
Bo 31 05-2013-30 (2)Bo 31 05-2013-30 (2)
Bo 31 05-2013-30 (2)
 
Why Smart Employees Underperform
Why Smart Employees UnderperformWhy Smart Employees Underperform
Why Smart Employees Underperform
 
Fracas escolar? La solució inesperada del gènere i la coeducació
Fracas escolar? La solució inesperada del gènere i la coeducacióFracas escolar? La solució inesperada del gènere i la coeducació
Fracas escolar? La solució inesperada del gènere i la coeducació
 
Wp3 refresh pgh
Wp3 refresh pghWp3 refresh pgh
Wp3 refresh pgh
 
Clda bmo01
Clda bmo01Clda bmo01
Clda bmo01
 
Rajul
RajulRajul
Rajul
 
As aves que frequentam a nossa escola
As aves que frequentam a nossa escolaAs aves que frequentam a nossa escola
As aves que frequentam a nossa escola
 

Similar a Developing BlockAlertViews for iOS Apps

My Favourite 10 Things about Xcode/ObjectiveC
My Favourite 10 Things about Xcode/ObjectiveCMy Favourite 10 Things about Xcode/ObjectiveC
My Favourite 10 Things about Xcode/ObjectiveCJohnKennedy
 
Quick Start to iOS Development
Quick Start to iOS DevelopmentQuick Start to iOS Development
Quick Start to iOS DevelopmentJussi Pohjolainen
 
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo KumperaAdvanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo KumperaXamarin
 
Converting Your Mobile App to the Mobile Cloud
Converting Your Mobile App to the Mobile CloudConverting Your Mobile App to the Mobile Cloud
Converting Your Mobile App to the Mobile CloudRoger Brinkley
 
New to native? Getting Started With iOS Development
New to native?   Getting Started With iOS DevelopmentNew to native?   Getting Started With iOS Development
New to native? Getting Started With iOS DevelopmentGeoffrey Goetz
 
Android Study Jams- Day 2(Hands on Experience)
Android Study Jams- Day 2(Hands on Experience)Android Study Jams- Day 2(Hands on Experience)
Android Study Jams- Day 2(Hands on Experience)GoogleDSC
 
iPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてiPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてKyosuke Takayama
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder BehindJohn Wilker
 
The Life and Times of UIViewController
The Life and Times of UIViewControllerThe Life and Times of UIViewController
The Life and Times of UIViewControllerwhilethis
 
A tour through Swift attributes
A tour through Swift attributesA tour through Swift attributes
A tour through Swift attributesMarco Eidinger
 
iPhone SDK dev sharing - the very basics
iPhone SDK dev sharing - the very basicsiPhone SDK dev sharing - the very basics
iPhone SDK dev sharing - the very basicskenshin03
 
iOS Beginners Lesson 4
iOS Beginners Lesson 4iOS Beginners Lesson 4
iOS Beginners Lesson 4Calvin Cheng
 
iOS: Implementing a Custom View
iOS: Implementing a Custom ViewiOS: Implementing a Custom View
iOS: Implementing a Custom ViewJussi Pohjolainen
 
iOS Contact List Application Tutorial
iOS Contact List Application TutorialiOS Contact List Application Tutorial
iOS Contact List Application TutorialIshara Amarasekera
 

Similar a Developing BlockAlertViews for iOS Apps (20)

My Favourite 10 Things about Xcode/ObjectiveC
My Favourite 10 Things about Xcode/ObjectiveCMy Favourite 10 Things about Xcode/ObjectiveC
My Favourite 10 Things about Xcode/ObjectiveC
 
iOS
iOSiOS
iOS
 
Quick Start to iOS Development
Quick Start to iOS DevelopmentQuick Start to iOS Development
Quick Start to iOS Development
 
I os 11
I os 11I os 11
I os 11
 
iphonedevcon 2010: Cooking with iAd
iphonedevcon 2010:  Cooking with iAd iphonedevcon 2010:  Cooking with iAd
iphonedevcon 2010: Cooking with iAd
 
Knockoutjs
KnockoutjsKnockoutjs
Knockoutjs
 
iOS testing
iOS testingiOS testing
iOS testing
 
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo KumperaAdvanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
 
Converting Your Mobile App to the Mobile Cloud
Converting Your Mobile App to the Mobile CloudConverting Your Mobile App to the Mobile Cloud
Converting Your Mobile App to the Mobile Cloud
 
New to native? Getting Started With iOS Development
New to native?   Getting Started With iOS DevelopmentNew to native?   Getting Started With iOS Development
New to native? Getting Started With iOS Development
 
Android Study Jams- Day 2(Hands on Experience)
Android Study Jams- Day 2(Hands on Experience)Android Study Jams- Day 2(Hands on Experience)
Android Study Jams- Day 2(Hands on Experience)
 
SkinKit
SkinKitSkinKit
SkinKit
 
iPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてiPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについて
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
 
The Life and Times of UIViewController
The Life and Times of UIViewControllerThe Life and Times of UIViewController
The Life and Times of UIViewController
 
A tour through Swift attributes
A tour through Swift attributesA tour through Swift attributes
A tour through Swift attributes
 
iPhone SDK dev sharing - the very basics
iPhone SDK dev sharing - the very basicsiPhone SDK dev sharing - the very basics
iPhone SDK dev sharing - the very basics
 
iOS Beginners Lesson 4
iOS Beginners Lesson 4iOS Beginners Lesson 4
iOS Beginners Lesson 4
 
iOS: Implementing a Custom View
iOS: Implementing a Custom ViewiOS: Implementing a Custom View
iOS: Implementing a Custom View
 
iOS Contact List Application Tutorial
iOS Contact List Application TutorialiOS Contact List Application Tutorial
iOS Contact List Application Tutorial
 

Último

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Último (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

Developing BlockAlertViews for iOS Apps

  • 1. What I’ve learned when developing BlockAlertViews Gustavo Ambrozio 360iDev 2012 Tuesday, September 11, 12
  • 2. About me • Developing professionally since age of 15 Tuesday, September 11, 12
  • 3. About me • Developing professionally since age of 15 • For iOS since the official SDK came out Tuesday, September 11, 12
  • 4. About me • Developing professionally since age of 15 • For iOS since the official SDK came out • Did some apps and contracts as an independent developer in Brazil Tuesday, September 11, 12
  • 5. About me • Developing professionally since age of 15 • For iOS since the official SDK came out • Did some apps and contracts as an independent developer in Brazil • Writter for raywenderlich.com Tuesday, September 11, 12
  • 6. About me • Developing professionally since age of 15 • For iOS since the official SDK came out • Did some apps and contracts as an independent developer in Brazil • Writter for raywenderlich.com • Hired by PocketGems to code games in SF Tuesday, September 11, 12
  • 7. About me • Developing professionally since age of 15 • For iOS since the official SDK came out • Did some apps and contracts as an independent developer in Brazil • Writter for raywenderlich.com • Hired by PocketGems to code games in SF • Hate engligh prepositions Tuesday, September 11, 12
  • 11. My love and hate story with UIAlertView • (apparently) Easy to use • Delegates • Switches • Tags • Constants Tuesday, September 11, 12
  • 12. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to” message:@”Send message using:” delegate:self cancelButtonTitle:@”Cancel” otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil]; view.tag = kSendAlertView; [view show]; [view release]; } Tuesday, September 11, 12
  • 13. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to” message:@”Send message using:” delegate:self cancelButtonTitle:@”Cancel” otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil]; view.tag = kSendAlertView; [view show]; [view release]; } Tuesday, September 11, 12
  • 14. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to” message:@”Send message using:” delegate:self cancelButtonTitle:@”Cancel” otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil]; view.tag = kSendAlertView; [view show]; [view release]; } Tuesday, September 11, 12
  • 15. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { UIAlertView *view = [[UIAlertView alloc] initWithTitle:@”Send to” message:@”Send message using:” delegate:self cancelButtonTitle:@”Cancel” otherButtonTitles:@”Twitter”, @”Facebook”, @”Email”, nil]; view.tag = kSendAlertView; [view show]; [view release]; } Tuesday, September 11, 12
  • 16. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { switch (alertView.tag) { case kRemoveConfirmAlertView: if (buttonIndex == 1) [self removeItem]; break; case kSendAlertView: { switch (buttonIndex) { case 0: // Cancel break; case 1: // Twitter [self sendWith:kTwitter]; break; case 2: // Facebook [self sendWith:kFacebook]; break; case 3: // email MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; break; } } break; } } Tuesday, September 11, 12
  • 17. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { switch (alertView.tag) { case kRemoveConfirmAlertView: if (buttonIndex == 1) [self removeItem]; break; case kSendAlertView: { switch (buttonIndex) { case 0: // Cancel break; case 1: // Twitter [self sendWith:kTwitter]; break; case 2: // Facebook [self sendWith:kFacebook]; break; case 3: // email MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; break; } } break; } } Tuesday, September 11, 12
  • 18. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { switch (alertView.tag) { case kRemoveConfirmAlertView: if (buttonIndex == 1) [self removeItem]; break; case kSendAlertView: { switch (buttonIndex) { case 0: // Cancel break; case 1: // Twitter [self sendWith:kTwitter]; break; case 2: // Facebook [self sendWith:kFacebook]; break; case 3: // email MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; break; } } break; } } Tuesday, September 11, 12
  • 19. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { switch (alertView.tag) { case kRemoveConfirmAlertView: if (buttonIndex == 1) [self removeItem]; break; case kSendAlertView: { switch (buttonIndex) { case 0: // Cancel break; case 1: // Twitter [self sendWith:kTwitter]; break; case 2: // Facebook [self sendWith:kFacebook]; break; case 3: // email MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; break; } } break; } } Tuesday, September 11, 12
  • 20. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { switch (alertView.tag) { case kRemoveConfirmAlertView: if (buttonIndex == 1) [self removeItem]; break; case kSendAlertView: { switch (buttonIndex) { case 0: // Cancel break; case 1: // Twitter [self sendWith:kTwitter]; break; case 2: // Facebook [self sendWith:kFacebook]; break; case 3: // email MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; break; } } break; } } Tuesday, September 11, 12
  • 21. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { switch (alertView.tag) { case kRemoveConfirmAlertView: if (buttonIndex == 1) [self removeItem]; break; case kSendAlertView: { switch (buttonIndex) { case 0: // Cancel break; case 1: // Twitter [self sendWith:kTwitter]; break; case 2: // Facebook [self sendWith:kFacebook]; break; case 3: // email MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; break; } } break; } } Tuesday, September 11, 12
  • 22. How blocks ended my hatred • PSFoundation (https://github.com/steipete/ PSFoundation/tree/master/Utils) • Peter Steinberger Tuesday, September 11, 12
  • 23. How blocks ended my hatred • PSFoundation (https://github.com/steipete/ PSFoundation/tree/master/Utils) • Peter Steinberger • PSAlertView e PSActionSheet Tuesday, September 11, 12
  • 24. How blocks ended my hatred • PSFoundation (https://github.com/steipete/ PSFoundation/tree/master/Utils) • Peter Steinberger • PSAlertView e PSActionSheet • Renamed to BlockAlertView and BlockActionSheet Tuesday, September 11, 12
  • 25. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view addButtonWithTitle:@”Email”, block:^{ MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; }]; view .tag = kSendAlertView; [view show]; } Tuesday, September 11, 12
  • 26. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view addButtonWithTitle:@”Email”, block:^{ MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; }]; view .tag = kSendAlertView; [view show]; } Tuesday, September 11, 12
  • 27. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view addButtonWithTitle:@”Email”, block:^{ MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; }]; view .tag = kSendAlertView; [view show]; } Tuesday, September 11, 12
  • 28. @interface MyViewController : UIViewController <UIAlertViewDelegate> #define kRemoveConfirmAlertView 1 #define kSendAlertView 2 #define kLogoutConfirmAlertView 3 - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlocAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view addButtonWithTitle:@”Email”, block:^{ MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; }]; view .tag = kSendAlertView; [view show]; } Tuesday, September 11, 12
  • 29. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view addButtonWithTitle:@”Email”, block:^{ MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; }]; [view show]; } Tuesday, September 11, 12
  • 30. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view addButtonWithTitle:@”Email”, block:^{ MFMailComposeViewController *view = [[MFMailComposeViewController alloc] init]; view.mailComposeDelegate = self; [self.navigationController presentModalViewController:view animated:YES]; }]; [view show]; } Tuesday, September 11, 12
  • 31. Lesson number 1 1. Use blocks instead of delegates (almost) all the time Tuesday, September 11, 12
  • 32. Lesson number 1 1. Use blocks instead of delegates (almost) all the time • Exception: When the block can retain something that can be deallocated before que block call gets made (NSURLConnections for example) Tuesday, September 11, 12
  • 33. How to do it 1. Subclass the original class and have it conform with it’s delegate. 2. Create typedefs for all blocks 3. Create @property for all blocks with (copy) 4. Implement all init methods and set self as delegate. 5. Implement all delegates, create ivars for all and call them if not nil. Tuesday, September 11, 12
  • 34. ARC compatibility • Simple: #if ! __has_feature(objc_arc) #error This file must be compiled with ARC. Please add -fobjc-arc to the compiler flags of this file. #endif • Better: Use Nick Lockwood’s ARC Helper .h file: https://gist.github.com/1563325 Tuesday, September 11, 12
  • 35. Improving AVAudioPlayer #import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> #import "ARCHelper.h" typedef void (^AudioPlayerDidFinishPlayingBlock)(BOOL); typedef void (^AudioPlayerDecodeErrorDidOccurBlock)(NSError *); typedef void (^AudioPlayerBeginInterruptionBlock)(); typedef void (^AudioPlayerEndInterruptionBlock)(NSUInteger); @interface BlockAudioPlayer : AVAudioPlayer <AVAudioPlayerDelegate> @property (nonatomic, copy) AudioPlayerDidFinishPlayingBlock audioPlayerDidFinishPlayingBlock; @property (nonatomic, copy) AudioPlayerDecodeErrorDidOccurBlock audioPlayerDecodeErrorDidOccurBlock; @property (nonatomic, copy) AudioPlayerBeginInterruptionBlock audioPlayerBeginInterruptionBlock; @property (nonatomic, copy) AudioPlayerEndInterruptionBlock audioPlayerEndInterruptionBlock; @end Tuesday, September 11, 12
  • 36. Improving AVAudioPlayer - (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError { self = [super initWithContentsOfURL:url error:outError]; if (self) { self.delegate = self; } return self; } #pragma mark - AVAudioPlayerDelegate - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { if (audioPlayerDidFinishPlayingBlock) audioPlayerDidFinishPlayingBlock(flag); } https://github.com/gpambrozio/BlockAudioPlayer Zachary Waldowski’s https://github.com/zwaldowski/BlocksKit Tuesday, September 11, 12
  • 37. Hate comes back with a new face Tuesday, September 11, 12
  • 38. Hate comes back with a new face Tuesday, September 11, 12
  • 39. Hate comes back with a new face Tuesday, September 11, 12
  • 40. A vision on how to end this hatred Tuesday, September 11, 12
  • 41. A vision on how to end this hatred Tuesday, September 11, 12
  • 42. A vision on how to end this hatred Tuesday, September 11, 12
  • 43. A vision on how to end this hatred Tuesday, September 11, 12
  • 44. Striking hatred with code Tuesday, September 11, 12
  • 45. Striking hatred with code Tuesday, September 11, 12
  • 46. Striking hatred with code UIWindow UView UILabel UIButton Tuesday, September 11, 12
  • 47. Striking hatred with code UIWindow UView UILabel UIButton Tuesday, September 11, 12
  • 48. Striking hatred with code UIWindow UView UILabel UIButton Tuesday, September 11, 12
  • 49. Lesson number 2 2. UIWindow is an unkown obscure class that’s very rarely used (and with very poor documentation) but that might solve some tricky UI problems. Use with care. Tuesday, September 11, 12
  • 50. UIWindow basics • No hierarchy. UIWindow are ordered using their windowLevel: • UIWindowLevelNormal • UIWIndowLevelAlert • UIWindowLevelStatusBar • If on the same level, ordered by creation time, last on top. • makeKeyAndVisible can push it to the top, but still respecting windowLevel. Tuesday, September 11, 12
  • 51. Key Window • From the docs: “...window which is currently receiving keyboard events and other non touch-related events. Whereas touch events are delivered to the window in which the touch occurred, events that do not have an associated coordinate value are delivered to the key window of your application. Only one window at a time may be key." • When you create a UIWindow and call makeKeyWindow, don’t just call resignKeyWindow. Save the previous keyWindow and call makeKeyWindow on it when you’re done. Tuesday, September 11, 12
  • 53. Lessons number 3 and 4 3. Open your mind to other libraries and don’t assume you need to do it the Apple way Tuesday, September 11, 12
  • 54. Lessons number 3 and 4 3. Open your mind to other libraries and don’t assume you need to do it the Apple way 4. Don’t be lazy. It’s fun to implement something from scratch. Tuesday, September 11, 12
  • 55. Spreading the love • BlockAlertView and BlockActionSheets are open source • github.com/gpambrozio/BlockAlertsAnd- ActionSheets Tuesday, September 11, 12
  • 56. Spreading the love • BlockAlertView and BlockActionSheets are open source • github.com/gpambrozio/BlockAlertsAnd- ActionSheets • blog.codecropper.com/2012/01/replicating- tweetbot-alerts-and-action-sheets/ Tuesday, September 11, 12
  • 57. Spreading the love • BlockAlertView and BlockActionSheets are open source • github.com/gpambrozio/BlockAlertsAnd- ActionSheets • blog.codecropper.com/2012/01/replicating- tweetbot-alerts-and-action-sheets/ • Improvements to UIAlertView and UIActionSheet Tuesday, September 11, 12
  • 58. Spreading the love • Import 6 files, 3 .h and 3 .m Tuesday, September 11, 12
  • 59. Spreading the love • Import 6 files, 3 .h and 3 .m • Copy 1 .h file with UI attributes Tuesday, September 11, 12
  • 60. Spreading the love • Import 6 files, 3 .h and 3 .m • Copy 1 .h file with UI attributes • Copy PNG assets or create your own Tuesday, September 11, 12
  • 61. Spreading the love • Import 6 files, 3 .h and 3 .m • Copy 1 .h file with UI attributes • Copy PNG assets or create your own • Change UI (optional) Tuesday, September 11, 12
  • 62. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view setDestructiveButtonWithTitle:@”Delete”, block:^{ [self removeItem]; }]; [view show]; } Tuesday, September 11, 12
  • 63. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view setDestructiveButtonWithTitle:@”Delete”, block:^{ [self removeItem]; }]; [view show]; } Tuesday, September 11, 12
  • 64. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view setDestructiveButtonWithTitle:@”Delete”, block:^{ [self removeItem]; }]; [view show]; } Tuesday, September 11, 12
  • 65. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view setDestructiveButtonWithTitle:@”Delete”, block:^{ [self removeItem]; }]; [view show]; } Tuesday, September 11, 12
  • 66. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view setDestructiveButtonWithTitle:@”Delete”, block:^{ [self removeItem]; }]; [view show]; } Tuesday, September 11, 12
  • 67. - (IBAction)sendItem:(id)sender { BlockAlertView *view = [BlockAlertView alertWithTitle:@”Send to” message:@”Send message using:”]; [view setCancelButtonWithTitle:@”Cancel” block:nil]; [view addButtonWithTitle:@”Twitter”, block:^{ [self sendWith:kTwitter]; }]; [view addButtonWithTitle:@”Facebook”, block:^{ [self sendWith:kFacebook]; }]; [view setDestructiveButtonWithTitle:@”Delete”, block:^{ [self removeItem]; }]; [view show]; } Tuesday, September 11, 12
  • 68. Spreading the love Tuesday, September 11, 12
  • 69. Spreading the love Tuesday, September 11, 12
  • 70. Advanced love • Background and buttons and simple PNGs Tuesday, September 11, 12
  • 71. Advanced love • It’s only an UIView.... [BlockBackground sharedInstance] UIView Tuesday, September 11, 12
  • 72. Advanced love • BlockTextPromptAlertView Tuesday, September 11, 12
  • 80. Lesson number 5 5. Opening your source is good: Improves your karma, your reputation and your source code. Tuesday, September 11, 12
  • 81. Gustavo Ambrozio • @gpambrozio • blog.codecropper.com • github.com/gpambrozio • linkedin.com/in/gustavoambrozio Tuesday, September 11, 12
  • 82. We’re hiring 2 apps in top 25 grossing apps Tuesday, September 11, 12