-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathListViewController.m
221 lines (171 loc) · 8.88 KB
/
ListViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//
// ListViewController.m
// Nerdfeed
//
// Created by THOMAS PENG on 6/18/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "ListViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
#import "ChannelViewController.h"
#import "BNRFeedStore.h"
@implementation ListViewController
@synthesize webViewController;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(storeUpdated:) name:BNRFeedStoreUpdateNotification object:nil];
UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:@"Info" style:UIBarButtonItemStyleBordered target:self action:@selector(showInfo:)];
[[self navigationItem] setRightBarButtonItem:bbi];
UISegmentedControl *rssTypeControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"BNR", @"Apple", nil]];
[rssTypeControl setSelectedSegmentIndex:0];
[rssTypeControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[rssTypeControl addTarget:self action:@selector(changeType:) forControlEvents:UIControlEventValueChanged];
[[self navigationItem] setTitleView:rssTypeControl];
[self fetchEntries];
}
return self;
}
- (void)storeUpdated:(NSNotification *)note
{
[[self tableView] reloadData];
}
- (void)changeType:(id)sender
{
rssType = [sender selectedSegmentIndex];
[self fetchEntries];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[channel items] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
if (cell == nil ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
}
RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[item title]];
if ([[BNRFeedStore sharedStore] hasItemBeenRead:item]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (![self splitViewController])
// Push the web view controller onto the navigation stack - this implicitly
// creates the web view controller's view the first time through
[[self navigationController] pushViewController:webViewController animated:YES];
else {
// We have to create a new navigation controller, as the old one
// was only retained by the split view controller and is now gone
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:webViewController];
NSArray *vcs = [NSArray arrayWithObjects:[self navigationController], nav, nil];
[[self splitViewController] setViewControllers:vcs];
// Make the detail view controller the delegate of the split view controller
// - ignore this warning
[[self splitViewController] setDelegate:webViewController];
}
// Grab the selected item
RSSItem *entry = [[channel items] objectAtIndex:[indexPath row]];
[[BNRFeedStore sharedStore] markItemAsRead:entry];
// Immediately add a checkmark to this row
[[[self tableView] cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
[webViewController listViewController:self handleObject:entry];
}
- (void)fetchEntries
{
// Get ahold of the segmented control that is currently in the title view
UIView *currentTitleView = [[self navigationItem] titleView];
// Create an activity indicator and start it spinning in the nav bar
UIActivityIndicatorView *aiView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[[self navigationItem] setTitleView:aiView];
[aiView startAnimating];
void (^completionBlock)(RSSChannel *obj, NSError *err) =
^(RSSChannel *obj, NSError *err) {
NSLog(@"Completion block called!");
// When the request completes - success or failure - replace the activity
// indicator with the segmented control
[[self navigationItem] setTitleView:currentTitleView];
// When the request completes, this block will be called.
if (!err) {
// If everything went ok, grab the channel object and reload the table
channel = obj;
[[self tableView] reloadData];
} else {
// If things went bad, show an alert view
NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [err localizedDescription]];
// Create and show an alert view with this error displayed
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[av show];
}
};
// Initiate the request...
if (rssType == ListViewControllerRSSTypeBNR) {
channel = [[BNRFeedStore sharedStore] fetchRSSFeedWithCompletion:
^(RSSChannel *obj, NSError *err) {
// Replace the activity indicator.
[[self navigationItem] setTitleView:currentTitleView];
if (!err) {
// How many items are there currently?
int currentItemCount = [[channel items] count];
// Set our channel to the merged one
channel = obj;
// How many items are there now?
int newItemCount = [[channel items] count];
// For each new item, insert a new row. The data source
// will take care of the rest.
int itemDelta = newItemCount - currentItemCount;
if (itemDelta > 0) {
NSMutableArray *rows = [NSMutableArray array];
for (int i = 0; i < itemDelta; i++) {
NSIndexPath *ip = [NSIndexPath indexPathForRow:i inSection:0];
[rows addObject:ip];
}
[[self tableView] insertRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationTop];
}
}
}];
[[self tableView] reloadData];
} else if (rssType == ListVieWControllerRSSTypeApple)
[[BNRFeedStore sharedStore] fetchTopSongs:10 withCompletion:completionBlock];
NSLog(@"Executing code at the end of fetchEntries");
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
return YES;
return io == UIInterfaceOrientationPortrait;
}
- (void)showInfo:(id)sender
{
// Create the channel view controller
ChannelViewController *channelViewController = [[ChannelViewController alloc] initWithStyle:UITableViewStyleGrouped];
if ([self splitViewController]) {
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:channelViewController];
// Create an array with our nav controller and this new VC's nav controller
NSArray *vcs = [NSArray arrayWithObjects:[self navigationController], nvc, nil];
// Grab a pointer to the split view controller and reset its view controllers array
[[self splitViewController] setViewControllers:vcs];
// Make detail view controller the delegate of the split view controller
// - ignore this warning
[[self splitViewController] setDelegate:channelViewController];
// If a row has been selected, deselect it so that a row
// is not selected when viewing the info
NSIndexPath *selectedRow = [[self tableView] indexPathForSelectedRow];
if (selectedRow)
[[self tableView] deselectRowAtIndexPath:selectedRow animated:YES];
} else {
[[self navigationController] pushViewController:channelViewController animated:YES];
}
// Give the VC the channel object through the protocol message
[channelViewController listViewController:self handleObject:channel];
}
@end