Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Schlanke View Controller
Search
Chris Eidhof | @chriseidhof
October 05, 2013
Technology
3
570
Schlanke View Controller
Vortrag bei der Macoun 2013
Chris Eidhof | @chriseidhof
October 05, 2013
Tweet
Share
More Decks by Chris Eidhof | @chriseidhof
See All by Chris Eidhof | @chriseidhof
Dutch FP Day 2015
chriseidhof
2
380
Tiny Networking in Swift
chriseidhof
2
19k
Functional Swift - Brooklyn
chriseidhof
3
1.2k
Functional Swift - SF
chriseidhof
6
26k
Functional Swift
chriseidhof
6
1.3k
Functional Swift
chriseidhof
1
150
Functional Programming in Swift
chriseidhof
40
19k
Lighter View Controllers
chriseidhof
4
200
Parsing with Blocks
chriseidhof
2
230
Other Decks in Technology
See All in Technology
AI関数が早くなったので試してみよう
kumakura
0
120
みんなのSRE 〜チーム全員でのSRE活動にするための4つの取り組み〜
kakehashi
PRO
2
140
JAWS AI/ML #30 AI コーディング IDE "Kiro" を触ってみよう
inariku
3
270
AWS re:Inforce 2025 re:Cap Update Pickup & AWS Control Tower の運用における考慮ポイント
htan
1
200
私とAWSとの関わりの歩み~意志あるところに道は開けるかも?~
nagisa53
1
160
【新卒研修資料】数理最適化 / Mathematical Optimization
brainpadpr
25
11k
Claude Codeから我々が学ぶべきこと
s4yuba
6
1.8k
【Λ(らむだ)】最近のアプデ情報 / RPALT20250729
lambda
0
230
風が吹けばWHOISが使えなくなる~なぜWHOIS・RDAPはサーバー証明書のメール認証に使えなくなったのか~
orangemorishita
15
5.5k
「育てる」サーバーレス 〜チーム開発研修で学んだ、小さく始めて大きく拡張するAWS設計〜
yu_kod
1
250
AI時代の経営、Bet AI Vision #BetAIDay
layerx
PRO
1
1.7k
データエンジニアがクラシルでやりたいことの現在地
gappy50
3
850
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
750
Site-Speed That Sticks
csswizardry
10
750
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
The Cost Of JavaScript in 2023
addyosmani
51
8.7k
Adopting Sorbet at Scale
ufuk
77
9.5k
Git: the NoSQL Database
bkeepers
PRO
431
65k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.6k
Balancing Empowerment & Direction
lara
1
530
Transcript
Macoun ⌘ Vorbereitung: 1. Demos, Files im Finder anordnen. 2.
Alle Programme die man für Demos benötigt vorher(!) starten. Bpsw: Xcode, Terminal, Refelection. 3. Präsentation starten und auf Zeichen oder Signal warten. Samstag, 5. Oktober 13
Schlanke View Controller Chris Eidhof Den Titel der Session und
darunter den eigenen Namen eintragen. Logo links oben anstatt dem Platzhalter. Nur auf diesem Slide! Samstag, 5. Oktober 13
WERBUNG Verkaufe Gouda im Wohnwagen Samstag, 5. Oktober 13
UITabellenAnzeigerAbgeordnete Samstag, 5. Oktober 13
Was ist die größte Datei in deinem Projekt? Samstag, 5.
Oktober 13
Was ist die größte Datei in deinem Projekt? 0 200
400 600 800 Samstag, 5. Oktober 13
(image by Manu Cornet) Samstag, 5. Oktober 13
(image by Manu Cornet) Samstag, 5. Oktober 13
View Controller sind nicht wiederverwendbar Samstag, 5. Oktober 13
find . -name "*.m" -exec wc -l "{}" \; |
sort -n Samstag, 5. Oktober 13
154 ./ViewControllers/THUserPrioritiesViewController.m 154 ./ViewControllers/THZoomingNavigationController.m 155 ./Extensions/NSArray+Extensions.m 155 ./Extensions/UIView+Extensions.m 168 ./Controllers/THPriorityTimelineCollectionController.m
179 ./Controllers/THUserScreenInstancesController.m 183 ./ViewControllers/THRootViewController.m 183 ./ViewControllers/THScreenInstanceViewController.m 185 ./Model/User+Extensions.m 192 ./ViewControllers/THEditPriorityViewController.m 221 ./ViewControllers/THScreeningBarViewController.m 243 ./Views/THTimeLineView.m 263 ./ViewControllers/THCardsViewController.m 279 ./Views/THSkillboxView.m Samstag, 5. Oktober 13
154 ./ViewControllers/THUserPrioritiesViewController.m 154 ./ViewControllers/THZoomingNavigationController.m 155 ./Extensions/NSArray+Extensions.m 155 ./Extensions/UIView+Extensions.m 168 ./Controllers/THPriorityTimelineCollectionController.m
179 ./Controllers/THUserScreenInstancesController.m 183 ./ViewControllers/THRootViewController.m 183 ./ViewControllers/THScreenInstanceViewController.m 185 ./Model/User+Extensions.m 192 ./ViewControllers/THEditPriorityViewController.m 221 ./ViewControllers/THScreeningBarViewController.m 243 ./Views/THTimeLineView.m 263 ./ViewControllers/THCardsViewController.m 279 ./Views/THSkillboxView.m Samstag, 5. Oktober 13
512 ./Classes/LessonResultViewController.m 514 ./Classes/Libs/ASIHTTPRequest/ASIDownloadCache.m 598 ./Classes/MainViewController.m 605 ./Classes/GameStartViewController.m 803 ./Classes/ResultViewController.m
818 ./Classes/RootViewController.m 1000 ./Classes/RankingViewController.m 1465 ./Classes/QuestionViewController.m 1590 ./Classes/REDACTEDAppDelegate.m 5125 ./Classes/Libs/ASIHTTPRequest/ASIHTTPRequest.m Samstag, 5. Oktober 13
... na gut, aber das ist ein wichtiger View Controller...
Samstag, 5. Oktober 13
STEPS Project Komplettes Betriebssystem in < 20K Zeilen Samstag, 5.
Oktober 13
Was können wir tun? Samstag, 5. Oktober 13
Ein View Controller vermittelt zwischen Modell und View Samstag, 5.
Oktober 13
Modelllogik Samstag, 5. Oktober 13
Viewlogik Samstag, 5. Oktober 13
Layout Samstag, 5. Oktober 13
Webservice Samstag, 5. Oktober 13
View Controller Modell Child View Controller Webservice Samstag, 5. Oktober
13
Demo Samstag, 5. Oktober 13
View Controller Modell Child View Controller Webservice Samstag, 5. Oktober
13
View Controller Modell Child View Controller Webservice Samstag, 5. Oktober
13
View Controller Modell Child View Controller Webservice Samstag, 5. Oktober
13
Modelllogik Entweder im Modell oder in einer separaten Klasse Samstag,
5. Oktober 13
18 ./NestedTodoList/main.m 30 ./Item.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m
255 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13
18 ./NestedTodoList/main.m 30 ./Item.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m
255 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13
Verantwortlichkeiten •Views konfigurieren •Table View Delegate •Table View Datasource •Fetched
Results Controller Delegate •Items hinzufügen •Items löschen Samstag, 5. Oktober 13
} Separate Klasse Verantwortlichkeiten •Views konfigurieren •Table View Delegate •Table
View Datasource •Fetched Results Controller Delegate •Items hinzufügen •Items löschen Samstag, 5. Oktober 13
} Separate Klasse Verantwortlichkeiten •Views konfigurieren •Table View Delegate •Table
View Datasource •Fetched Results Controller Delegate •Items hinzufügen •Items löschen } Modell Samstag, 5. Oktober 13
- (BOOL)textFieldShouldReturn:(UITextField*)t { NSString* title = t.text; NSUInteger order =
self.parent.children.count; Item* item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.moc]; item.title = title; item.parent = self.parent; item.order = @(order); ... } Modell Samstag, 5. Oktober 13
- (BOOL)textFieldShouldReturn:(UITextField*)t { NSString* title = t.text; NSUInteger order =
self.parent.children.count; [Item insertItemWithTitle:title parent:self.parent inManagedObjectContext:self.moc]; ... } Modell Samstag, 5. Oktober 13
- (void)deleteItem:(id)object { Item* item = object; NSSet* siblings =
item.parent.children; NSPredicate* predicate = [NSPredicate predicateWithFormat:@"order > %@", item.order]; NSSet* itemsAfterSelf = [siblings filteredSetUsingPredicate:predicate]; [itemsAfterSelf enumerateObjectsUsingBlock:^(Item* sibling, BOOL* stop) { sibling.order = @(sibling.order.integerValue - 1); }]; [item.moc deleteObject:item]; } Samstag, 5. Oktober 13
- (void)deleteItem:(id)object { Item* item = object; NSSet* siblings =
item.parent.children; NSPredicate* predicate = [NSPredicate predicateWithFormat:@"order > %@", item.order]; NSSet* itemsAfterSelf = [siblings filteredSetUsingPredicate:predicate]; [itemsAfterSelf enumerateObjectsUsingBlock:^(Item* sibling, BOOL* stop) { sibling.order = @(sibling.order.integerValue - 1); }]; [item.moc deleteObject:item]; } Samstag, 5. Oktober 13
- (void)prepareForDeletion { NSSet* siblings = self.parent.children; NSPredicate* p =
[NSPredicate predicateWithFormat:@"order > %@", self.order]; NSSet* itemsAfterSelf = [siblings filteredSetUsingPredicate:p]; [itemsAfterSelf enumerateObjectsUsingBlock: ^(Item* sibling, BOOL* stop) { sibling.order = @(sibling.order.integerValue - 1); }]; } Samstag, 5. Oktober 13
18 ./NestedTodoList/main.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 54 ./Item.m
241 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13
18 ./NestedTodoList/main.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 54 ./Item.m
241 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13
View Controller Modell Child View Controller Webservice UITableViewDS Samstag, 5.
Oktober 13
View Controller Modell Child View Controller Webservice UITableViewDS Samstag, 5.
Oktober 13
@interface FetchedResultsControllerDataSource : NSObject <UITableViewDataSource, NSFetchedResultsControllerDelegate> Samstag, 5. Oktober 13
- (NSInteger)numberOfSectionsInTableView:(UITableView*)t { return self.fetchedResultsController.sections.count; } Samstag, 5. Oktober 13
- (NSInteger)tableView:(UITableView*)t numberOfRowsInSection:(NSInteger)s { id<NSFetchedResultsSectionInfo> section = self.fetchedResultsController.sections[s]; return section.numberOfObjects;
} Samstag, 5. Oktober 13
- (UITableViewCell*)tableView:(UITableView*)t cellForRowAtIndexPath:(NSIndexPath*)ip ? Samstag, 5. Oktober 13
#pragma mark NSFetchedResultsControllerDelegate Samstag, 5. Oktober 13
- (void)controller:(NSFetchedResultsController*)c didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)ct newIndexPath:(NSIndexPath*)newIndexPath Samstag, 5. Oktober 13
@property (nonatomic, weak) id <FRCDataSourceDelegate> delegate; Samstag, 5. Oktober 13
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { id object = [self.frc objectAtIndexPath:indexPath]; id
cell = [tableView dequeueReusableCellWithIdentifier:self.reuseIdentifier forIndexPath:indexPath]; [self.delegate configureCell:cell withObject:object]; return cell; } Samstag, 5. Oktober 13
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { id object = [self.frc objectAtIndexPath:indexPath]; id
cell = [tableView dequeueReusableCellWithIdentifier:self.reuseIdentifier forIndexPath:indexPath]; [self.delegate configureCell:cell withObject:object]; return cell; } Samstag, 5. Oktober 13
Demo Samstag, 5. Oktober 13
25 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 64 ./Item.m 111 ./NestedTodoList/FRCDataSource.m
162 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13
25 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 64 ./Item.m 111 ./NestedTodoList/FRCDataSource.m
162 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13
Wiederverwendbarkeit Samstag, 5. Oktober 13
Oder eine Oberklasse? Samstag, 5. Oktober 13
Nachteile von Oberklassen Es gibt nur eine Oberklasse Schwerer zu
wechseln, z.B. von UITableView nach UICollectionView Fehleranfälliger: z.B. super calls vergessen Samstag, 5. Oktober 13
Andere Kandidaten UICollectionViewDataSource UIPageViewControllerDataSource UIPickerViewDataSource Samstag, 5. Oktober 13
Mehr Kandidaten UICollectionViewDelegate UIScrollViewDelegate UITableViewDelegate UITableViewDelegate UITextFieldDelegate UINavigationControllerDelegate Samstag, 5.
Oktober 13
View Controller Modell Child View Controller Webservice Samstag, 5. Oktober
13
View Controller Modell Child View Controller Webservice Samstag, 5. Oktober
13
- (UITableViewCell*)tableView:(UITableView*)t cellForRowAtIndexPath:(NSIndexPath*)ip Samstag, 5. Oktober 13
@interface PhotoCell (ConfigureForPhoto) - (void)configureForPhoto:(Photo *)photo; @end PhotoCell+ConfigureForPhoto.h Samstag, 5.
Oktober 13
UITableViewController •Löscht Selektion •Daten neu laden •Scroll indicators zeigen •Editieren
•Scrollen zum first responder •Refresh control •.... Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
View Controller Containment Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
[self addChildViewController:sliderController]; [self.view addSubview:sliderController.view]; [UIView animateWithDuration:0.25 animations:^{ sliderController.view.alpha = 1;
} completion:^(BOOL finished) { [sliderController didMoveToParentViewController:self]; }]; ... oder im Kode Samstag, 5. Oktober 13
Kommunikation Samstag, 5. Oktober 13
Kommunikation •Delegate •Blocks •KVO Samstag, 5. Oktober 13
Kommunikation •Delegate •Blocks •KVO Zu viel? Samstag, 5. Oktober 13
Interface Builder Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
@interface MyCell : UITableViewCell @property (weak) IBOutlet UISlider *slider; @property
(weak) IBOutlet UISwitch *switch; @end Samstag, 5. Oktober 13
Benutzerdefinierte Objekte im Nib Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
Outlets funktionieren auch Samstag, 5. Oktober 13
@interface NSObject(UINibLoadingAdditions) - (void)awakeFromNib; @end Samstag, 5. Oktober 13
Demo Samstag, 5. Oktober 13
Testen Samstag, 5. Oktober 13
Getrennte Data Source ✓ Samstag, 5. Oktober 13
Kategorie für eine Zelle ✓ Samstag, 5. Oktober 13
View Controller x Samstag, 5. Oktober 13
- (void)testNibLoading; { id mockNavController = [self autoVerifiedMockForClass: [UINavigationController class]];
PhotosViewController *photosViewController = [[PhotosViewController alloc] init]; id photosViewControllerMock = [self autoVerifiedPartialMockForObject: photosViewController]; [[[photosViewControllerMock stub] andReturn:mockNavController] navigationController]; Samstag, 5. Oktober 13
Werkzeuge •Dateien nach Länge sortieren •Bibliothekenkenntniss •Refactoring: AppCode Samstag, 5.
Oktober 13
Werkzeuge •Data Source extrahieren •View Controller Containment •Mehr im Modell,
mehr in Views Samstag, 5. Oktober 13
Über mich •@chriseidhof •http://www.objc.io •http://www.uikonf.com •
[email protected]
Samstag, 5. Oktober 13
Fragen? Samstag, 5. Oktober 13
Vielen Dank Samstag, 5. Oktober 13
Samstag, 5. Oktober 13
Hier ist das Ende Letzte Folie Macoun ⌘ Samstag, 5.
Oktober 13