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
オンプレとGoogle Cloudを安全に繋ぐための、セキュア通信の勘所
waiwai2111
3
1.1k
Oracle Cloud Infrastructure:2026年2月度サービス・アップデート
oracle4engineer
PRO
0
220
Kaggleの経験が実務にどう活きているか / kaggle_findy
sansan_randd
4
750
Oracle Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
4
1.1k
20260305_【白金鉱業】分析者が地理情報を武器にするための軽量なアドホック分析環境
yucho147
1
170
Databricksアシスタントが自分で考えて動く時代に! エージェントモード体験もくもく会
taka_aki
0
320
開発組織の課題解決を加速するための権限委譲 -する側、される側としての向き合い方-
daitasu
4
250
EMからICへ、二周目人材としてAI全振りのプロダクト開発で見つけた武器
yug1224
3
400
マネージャー版 "提案のレベル" を上げる
konifar
18
12k
プロジェクトマネジメントをチームに宿す -ゼロからはじめるチームプロジェクトマネジメントは活動1年未満のチームの教科書です- / 20260304 Shigeki Morizane
shift_evolve
PRO
1
110
「ストレッチゾーンに挑戦し続ける」ことって難しくないですか? メンバーの持続的成長を支えるEMの環境設計
sansantech
PRO
1
320
メタデータ同期に潜んでいた問題 〜 Cache Stampede 時の Cycle Wait を⾒つけた話
lycorptech_jp
PRO
0
150
Featured
See All Featured
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.5k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
200
Paper Plane (Part 1)
katiecoart
PRO
0
5.1k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
620
GraphQLとの向き合い方2022年版
quramy
50
14k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
0
2.4k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
760
Art, The Web, and Tiny UX
lynnandtonic
304
21k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
1.9k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
290
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