Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lighter View Controllers

Lighter View Controllers

Mobile Warsaw edition. Including Ultra Light View Controllers.

More Decks by Chris Eidhof | @chriseidhof

Other Decks in Technology

Transcript

  1. ⾠ “My point isn’t that it’s never a good idea

    to break up a large view controller. My point is that it’s worth noticing when it’s not actually helping, when it’s adding complexity - and that it’s worth finding the right balance, which takes some thinking.” Brent Simmons
  2. MVC

  3. MVC » Model code in model » View-related code in

    view (or IB) » Webservice in service layer
  4. Model code in model - (void)loadPriorities { NSDate* now =

    [NSDate date]; NSString* formatString = @"startDate <= %@ AND endDate >= %@"; NSPredicate* predicate = [NSPredicate predicateWithFormat:formatString, now, now]; NSSet* priorities = [self.user.priorities filteredSetUsingPredicate:predicate]; self.priorities = [priorities allObjects]; }
  5. Frameworks » Use the frameworks » Child View Controllers »

    View Controller Transitions for state » Optimize your VC for testability
  6. UITableViewController “When the table view is about to appear the

    first time it’s loaded, the table- view controller reloads the table view’s data. It also clears its selection every time the table view is displayed.” UITableViewController Class Reference
  7. UITableViewController “When the table view has appeared, the controller flashes

    the table view’s scroll indicators. The UITableViewController class implements this in the superclass method viewDidAppear:.” UITableViewController Class Reference
  8. UITableViewController “It implements the superclass method setEditing:animated: so that if

    a user taps an Edit|Done button in the navigation bar, the controller toggles the edit mode of the table.” UITableViewController Class Reference
  9. UITableViewController » Clears selection » Flashes scroll indicators » Editing

    behavior » Pull to refresh » Keyboard notifications
  10. A VC may only do work in viewDidLoad, viewDidAppear, viewDidDisappear,

    and in response to an observed change in the model layer.
  11. @interface ViewController () <UITextFieldDelegate> @property (weak, nonatomic) IBOutlet UILabel *label;

    @property (weak, nonatomic) IBOutlet UITextField *textField; @property (nonatomic, strong) Person* person; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.person = [Person new]; self.person.name = @"Chris"; [self updateTextField]; } #pragma mark Actions - (IBAction)reverse:(id)sender { self.person.name = self.textField.text.reversedString; [self updateTextField]; } - (IBAction)uppercase:(id)sender { self.person.name = self.textField.text.uppercaseString; [self updateTextField]; } #pragma mark UITextFieldDelegate - (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string { if ([string isEqualToString:@"\n"]) { [textField resignFirstResponder]; return NO; } return YES; } - (void)updateTextField { self.textField.text = self.person.name; } @end
  12. @interface ViewController () <UITextFieldDelegate> @property (weak, nonatomic) IBOutlet UILabel *label;

    @property (weak, nonatomic) IBOutlet UITextField *textField; @property (nonatomic, strong) Person* person; @end
  13. #pragma mark Actions - (IBAction)reverse:(id)sender { self.person.name = self.textField.text.reversedString; [self

    updateTextField]; } - (IBAction)uppercase:(id)sender { self.person.name = self.textField.text.uppercaseString; [self updateTextField]; }
  14. #pragma mark UITextFieldDelegate - (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string { if ([string

    isEqualToString:@"\n"]) { [textField resignFirstResponder]; return NO; } return YES; } - (void)updateTextField { self.textField.text = self.person.name; } @end
  15. find . -name '*.m' -exec wc -l {} + |

    sort -n 13 ./Intentions/AppDelegate.m 13 ./Intentions/ModelContainer.m 13 ./Intentions/Person.m 18 ./Intentions/main.m 19 ./Intentions/ViewController.m 22 ./Intentions/NSString+Reverse.m 26 ./Intentions/DismissOnEnterIntention.m 27 ./Intentions/ReverseIntention.m 27 ./Intentions/UppercaseIntention.m 45 ./Intentions/ObserveIntention.m
  16. - (void)viewDidLoad { [super viewDidLoad]; Person *person = [Person new];

    person.name = @"Chris"; self.modelContainer.model = person; }
  17. @interface UppercaseIntention () @property (weak) IBOutlet UITextField *textField; @property (weak)

    IBOutlet ModelContainer *modelContainer; @property (copy) NSString *modelKeyPath; @end @implementation UppercaseIntention - (IBAction)capitalize:(id)sender { [self.modelContainer.model setValue:self.textField.text.uppercaseString forKey:self.modelKeyPath]; } @end
  18. Plan of Attack 1.Put things into separate methods 2.Group the

    methods together 3.Move related methods into their own class