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
600
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
210
Parsing with Blocks
chriseidhof
2
240
Other Decks in Technology
See All in Technology
技術的負債の泥沼から組織を救う3つの転換点
nwiizo
8
3.6k
ナレッジワークのご紹介(第88回情報処理学会 )
kworkdev
PRO
0
180
Shifting from MCP to Skills / ベストプラクティスの変遷を辿る
yamanoku
4
790
新職業『オーケストレーター』誕生 — エージェント10体を同時に回すAgentOps
gunta
4
1.8k
Evolution of Claude Code & How to use features
oikon48
1
580
ランサムウエア対策してますか?やられた時の対策は本当にできてますか?AWSでのリスク分析と対応フローの泥臭いお話。
hootaki
0
110
元エンジニアPdM、IDEが恋しすぎてCursorに全業務を集約したら、スライド作成まで爆速になった話
doiko123
1
590
Datadog の RBAC のすべて
nulabinc
PRO
3
440
マネージャー版 "提案のレベル" を上げる
konifar
22
15k
作りっぱなしで終わらせない! 価値を出し続ける AI エージェントのための「信頼性」設計 / Designing Reliability for AI Agents that Deliver Continuous Value
aoto
PRO
2
280
僕、S3 シンプルって名前だけど全然シンプルじゃありません よろしくお願いします
yama3133
1
190
決済サービスを支えるElastic Cloud - Elastic Cloudの導入と推進、決済サービスのObservability
suzukij
2
600
Featured
See All Featured
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
120
What's in a price? How to price your products and services
michaelherold
247
13k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
130
The Spectacular Lies of Maps
axbom
PRO
1
610
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.7k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
67
37k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
290
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.5k
Context Engineering - Making Every Token Count
addyosmani
9
740
Claude Code のすすめ
schroneko
67
220k
We Have a Design System, Now What?
morganepeng
55
8k
Thoughts on Productivity
jonyablonski
75
5.1k
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