Skip to content

Commit 3480fbb

Browse files
committed
improved interface for groups
1 parent bc7eb41 commit 3480fbb

7 files changed

+141
-47
lines changed

RSSReader/AppDelegate.swift

+12-4
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@ var rss : AppDelegate!
1515
class AppDelegate: UIResponder, UIApplicationDelegate {
1616

1717
var window: UIWindow! // the UI window
18-
var currentFeedVC: FeedListVC? // the current feed group VC
1918
var navigationController: UINavigationController! // the navigation controller
2019
var defaultGroup: FeedGroup! // the default feed group
2120

21+
var currentFeedVC: FeedListVC? { // the current feed group VC
22+
let vc = navigationController.topViewController
23+
if let feedVC = vc as? FeedListVC {
24+
return feedVC
25+
}
26+
return nil
27+
}
28+
2229
let feedQueue = NSOperationQueue() // queue for loading feeds
2330
let defaults = NSUserDefaults.standardUserDefaults() // standard user defaults
2431
let manager = Manager() // the single feed manager
@@ -36,11 +43,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3643

3744
// set up interface.
3845
window = UIWindow(frame: UIScreen.mainScreen().bounds)
39-
currentFeedVC = FeedDefaultVC(group: defaultGroup)
40-
navigationController = UINavigationController(rootViewController: currentFeedVC!)
46+
47+
let feedVC = FeedDefaultVC(group: defaultGroup)
48+
navigationController = UINavigationController(rootViewController: feedVC)
49+
4150
window.rootViewController = navigationController
4251
window.makeKeyAndVisible()
43-
4452
return true
4553
}
4654

RSSReader/ArticleListCell.xib

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14B17" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
33
<dependencies>
44
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
55
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>

RSSReader/ArticleListSmallCell.xib

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
33
<dependencies>
44
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
55
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>

RSSReader/ArticleWebVC.xib

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
33
<dependencies>
44
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
55
</dependencies>

RSSReader/Feed.swift

+14-4
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ class Feed: NSManagedObject, Printable, ArticleCollection, NSXMLParserDelegate {
138138
func addArticle(article: Article) {
139139

140140
// this one already exists; update it.
141+
NSLog("looking for ID \(article.identifier)")
141142
if articlesById[article.identifier] != nil {
143+
NSLog("exists")
142144
mutableArticles.removeObject(article)
143145
}
144146

@@ -181,14 +183,13 @@ class Feed: NSManagedObject, Printable, ArticleCollection, NSXMLParserDelegate {
181183
//NSLog("Parsing the data")
182184
let parser = XMLParser(feed: self, data: data)
183185
parser.parse()
184-
rss.currentFeedVC?.tableView.reloadData()
185186

186187
// download logo/icon.
187188
self.downloadImages()
188189

189-
// in the main queue, reload the table, then call callback.
190+
// in the main queue, update UI and call callback.
190191
mainQueue {
191-
rss.currentFeedVC?.tableView.reloadData()
192+
self.reloadCells()
192193
then?()
193194
}
194195

@@ -220,7 +221,7 @@ class Feed: NSManagedObject, Printable, ArticleCollection, NSXMLParserDelegate {
220221

221222
// reload the table in the main queue, if there is one visible.
222223
mainQueue {
223-
rss.currentFeedVC?.tableView.reloadData()
224+
self.reloadCells()
224225
return
225226
}
226227

@@ -242,6 +243,15 @@ class Feed: NSManagedObject, Printable, ArticleCollection, NSXMLParserDelegate {
242243
}
243244
}
244245

246+
// reload the visible cells associated with the feed, if any.
247+
func reloadCells() {
248+
if let feedVC = rss.currentFeedVC {
249+
let path = NSIndexPath(forRow: find(feedVC.group.feeds, self)!, inSection: feedVC.secFeedList)
250+
NSLog("path: \(path)")
251+
feedVC.tableView.reloadRowsAtIndexPaths([path], withRowAnimation: .Automatic)
252+
}
253+
}
254+
245255
// convenience for fetching with no callback.
246256
func fetch() {
247257
fetchThen(nil)

RSSReader/FeedDefaultVC.swift

+89-25
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ import UIKit
1010
import CoreData
1111

1212
class FeedDefaultVC: FeedListVC {
13+
private var _textField : UITextField?
1314

15+
override var secAllArticles: Int { return 0 }
16+
var secGroupList: Int { return 1 }
17+
override var secFeedList: Int { return 2 }
18+
1419
override func viewDidLoad() {
1520
super.viewDidLoad()
1621
self.navigationItem.title = "Feeds"
@@ -28,35 +33,55 @@ class FeedDefaultVC: FeedListVC {
2833
// 1 = group list
2934
// 2 = feeds in default group
3035
switch section {
31-
case 0: return 1
32-
case 1: return rss.manager.notDefaultGroups.count
33-
case 2: return group.feeds.count
36+
case secAllArticles: return 1
37+
case secGroupList: return rss.manager.notDefaultGroups.count
38+
case secFeedList: return group.feeds.count
3439
default: return 0
3540
}
41+
3642
}
3743

3844
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
3945
return 70
4046
}
4147

4248
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
43-
switch editingStyle {
49+
switch indexPath.section {
50+
51+
// group list edit.
52+
case secGroupList:
53+
return
4454

45-
case .Delete:
46-
47-
let feed = group.managedFeeds[indexPath.row] as Feed
48-
group.mutableFeeds.removeObject(feed)
49-
rss.manager.removeFeed(feed)
50-
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
55+
// default group feed list edit.
56+
case secFeedList:
57+
switch editingStyle {
58+
59+
case .Delete:
60+
61+
let feed = group.managedFeeds[indexPath.row] as Feed
62+
group.mutableFeeds.removeObject(feed)
63+
rss.manager.removeFeed(feed)
64+
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
5165

52-
// case .Insert:
53-
// case .None:
66+
// case .Insert:
67+
// case .None:
68+
69+
default: break
70+
}
5471

55-
default:
56-
break
72+
default: break
5773
}
5874
}
5975

76+
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
77+
return indexPath.section != secAllArticles
78+
}
79+
80+
// the "all articles" button cannot be moved.
81+
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
82+
return indexPath.section != secAllArticles
83+
}
84+
6085
override func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
6186
//FIXME: doesn't work.
6287
swap(&group.mutableFeeds[sourceIndexPath.row], &group.mutableFeeds[destinationIndexPath.row])
@@ -67,9 +92,9 @@ class FeedDefaultVC: FeedListVC {
6792
// 1 = group list
6893
// 2 = feeds in default group
6994
switch indexPath.section {
70-
case 0: return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
71-
case 1: return cellForGroupAtRow(indexPath.row)
72-
case 2:
95+
case secAllArticles: return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
96+
case secGroupList: return cellForGroupAtRow(indexPath.row)
97+
case secFeedList:
7398
let path = NSIndexPath(forRow: indexPath.row, inSection: 1)
7499
return super.tableView(tableView, cellForRowAtIndexPath: path)
75100
default: return UITableViewCell()
@@ -86,13 +111,19 @@ class FeedDefaultVC: FeedListVC {
86111
// user selected a feed.
87112
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
88113

89-
// group.
90-
if indexPath.section == 0 {
114+
// show all articles in all groups.
115+
if indexPath.section == secAllArticles {
91116
pushArticleViewToCollection(group)
92117
return
93118
}
94119

95-
// feed.
120+
// show feeds in group.
121+
if indexPath.section == secGroupList {
122+
let group = rss.manager.notDefaultGroups[indexPath.row]
123+
return pushFeedViewForGroup(group)
124+
}
125+
126+
// show articles in feed.
96127
let feed = group.feeds[indexPath.row]
97128

98129
// no articles; fetch them
@@ -105,18 +136,17 @@ class FeedDefaultVC: FeedListVC {
105136

106137

107138
func addButtonTappedTwo(sender: AnyObject) {
108-
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
109-
139+
let alert = UIAlertController(title: "Create new...", message: nil, preferredStyle: .ActionSheet)
140+
110141
// feed button.
111142
let action1 = UIAlertAction(title: "Feed", style: .Default) { _ in
112-
return self.addButtonTapped(sender)
143+
return self.presentFeedCreator(sender)
113144
}
114145
alert.addAction(action1)
115146

116147
// group button.
117148
let action2 = UIAlertAction(title: "Group", style: .Default) { _ in
118-
119-
return
149+
return self.presentGroupCreator(sender)
120150
}
121151
alert.addAction(action2)
122152

@@ -127,4 +157,38 @@ class FeedDefaultVC: FeedListVC {
127157
self.presentViewController(alert, animated: true, completion: nil)
128158

129159
}
160+
161+
func presentGroupCreator(sender: AnyObject) {
162+
let alert = UIAlertController(title: "Create group", message: nil, preferredStyle: .Alert)
163+
164+
// text field.
165+
alert.addTextFieldWithConfigurationHandler { textField in
166+
self._textField = textField
167+
textField.placeholder = "URL"
168+
}
169+
170+
// OK button.
171+
let action = UIAlertAction(title: "OK", style: .Default) { _ in
172+
173+
// empty string?
174+
let string = self._textField!.text!
175+
self._textField = nil
176+
if string.isEmpty { return }
177+
178+
// create the group.
179+
let group = rss.manager.newGroupTitled(string)
180+
rss.manager.addGroup(group)
181+
let path = NSIndexPath(forRow: rss.manager.notDefaultGroups.count - 1, inSection: self.secGroupList)
182+
self.tableView.insertRowsAtIndexPaths([path], withRowAnimation: .Automatic)
183+
184+
return
185+
}
186+
alert.addAction(action)
187+
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
188+
189+
// present it.
190+
self.presentViewController(alert, animated: true, completion: nil)
191+
192+
}
193+
130194
}

RSSReader/FeedListVC.swift

+23-11
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ import CoreData
1212
class FeedListVC: UITableViewController {
1313
private var _textField : UITextField?
1414
var group: FeedGroup!
15-
15+
16+
var secAllArticles: Int { return 0 }
17+
var secFeedList: Int { return 1 }
18+
1619
convenience init(group: FeedGroup) {
1720
self.init()
1821
self.group = group
1922
}
2023

2124
override func viewDidLoad() {
2225
self.navigationItem.title = group.title
23-
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "addButtonTapped:")
26+
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "presentFeedCreator:")
2427
self.navigationItem.leftBarButtonItem = self.editButtonItem()
2528
}
2629

@@ -32,16 +35,20 @@ class FeedListVC: UITableViewController {
3235

3336

3437
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
35-
return section == 0 ? 1 : group.feeds.count
38+
return section == secAllArticles ? 1 : group.feeds.count
3639
}
3740

3841
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
3942
return 70
4043
}
44+
45+
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
46+
return indexPath.section != secAllArticles
47+
}
4148

4249
// the "all articles" button cannot be moved.
4350
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
44-
return indexPath.section != 0
51+
return indexPath.section != secAllArticles
4552
}
4653

4754
// this is to prevent things from being moved between sections.
@@ -77,7 +84,7 @@ class FeedListVC: UITableViewController {
7784
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
7885

7986
// this is the top cell.
80-
if indexPath.section == 0 {
87+
if indexPath.section == secAllArticles {
8188
let cell = UITableViewCell(style: .Default, reuseIdentifier: nil)
8289
cell.textLabel.text = "All articles"
8390
cell.accessoryType = .DisclosureIndicator
@@ -108,8 +115,8 @@ class FeedListVC: UITableViewController {
108115
// user selected a feed.
109116
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
110117

111-
// group.
112-
if indexPath.section == 0 {
118+
// all articles.
119+
if indexPath.section == secAllArticles {
113120
pushArticleViewToCollection(group)
114121
return
115122
}
@@ -118,7 +125,7 @@ class FeedListVC: UITableViewController {
118125
let feed = group.feeds[indexPath.row]
119126

120127
// no articles; fetch them
121-
if feed.articles.count == 0 {
128+
if feed.articles.isEmpty {
122129
feed.fetch()
123130
}
124131

@@ -134,7 +141,7 @@ class FeedListVC: UITableViewController {
134141
self.navigationController?.pushViewController(artVC, animated: true)
135142
}
136143

137-
func addButtonTapped(sender: AnyObject) {
144+
func presentFeedCreator(sender: AnyObject) {
138145
let alert = UIAlertController(title: "Add feed", message: nil, preferredStyle: .Alert)
139146

140147
// text field.
@@ -149,7 +156,7 @@ class FeedListVC: UITableViewController {
149156
// empty string?
150157
let string = self._textField!.text!
151158
self._textField = nil
152-
if countElements(string) < 1 { return }
159+
if string.isEmpty { return }
153160

154161
// does the feed exist already? reload it.
155162
if let feed = rss.manager.feedFromURLString(string) {
@@ -175,5 +182,10 @@ class FeedListVC: UITableViewController {
175182
self.presentViewController(alert, animated: true, completion: nil)
176183

177184
}
178-
185+
186+
func pushFeedViewForGroup(group: FeedGroup) {
187+
let feedVC = FeedListVC(group: group)
188+
rss.navigationController.pushViewController(feedVC, animated: true)
189+
}
190+
179191
}

0 commit comments

Comments
 (0)