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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Chris Eidhof | @chriseidhof
October 05, 2013
Technology
3
590
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
390
Tiny Networking in Swift
chriseidhof
2
19k
Functional Swift - Brooklyn
chriseidhof
3
1.3k
Functional Swift - SF
chriseidhof
6
26k
Functional Swift
chriseidhof
6
1.3k
Functional Swift
chriseidhof
1
160
Functional Programming in Swift
chriseidhof
40
19k
Lighter View Controllers
chriseidhof
4
200
Parsing with Blocks
chriseidhof
2
240
Other Decks in Technology
See All in Technology
モダンUIでフルサーバーレスなAIエージェントをAmplifyとCDKでサクッとデプロイしよう
minorun365
3
150
Stately
mu7889yoon
1
100
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
340
今日から始めるAmazon Bedrock AgentCore
har1101
4
400
システムのアラート調査をサポートするAI Agentの紹介/Introduction to an AI Agent for System Alert Investigation
taddy_919
2
1.9k
MCPでつなぐElasticsearchとLLM - 深夜の障害対応を楽にしたい / Bridging Elasticsearch and LLMs with MCP
sashimimochi
0
140
使いにくいの壁を突破する
sansantech
PRO
1
120
SREが向き合う大規模リアーキテクチャ 〜信頼性とアジリティの両立〜
zepprix
0
410
日本語テキストと音楽の対照学習の技術とその応用
lycorptech_jp
PRO
1
430
Oracle Cloud Observability and Management Platform - OCI 運用監視サービス概要 -
oracle4engineer
PRO
2
14k
(金融庁共催)第4回金融データ活用チャレンジ勉強会資料
takumimukaiyama
0
130
CDK対応したAWS DevOps Agentを試そう_20260201
masakiokuda
1
200
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
6.8k
How to Ace a Technical Interview
jacobian
281
24k
Building AI with AI
inesmontani
PRO
1
680
Making the Leap to Tech Lead
cromwellryan
135
9.7k
GitHub's CSS Performance
jonrohan
1032
470k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
430
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
55
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
0
310
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
57
50k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
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