diff --git a/Kiwix-iOS/Controller/Search/SearchBooksController.swift b/Kiwix-iOS/Controller/Search/SearchBooksController.swift
index 9af7c71b..0b7b14ce 100644
--- a/Kiwix-iOS/Controller/Search/SearchBooksController.swift
+++ b/Kiwix-iOS/Controller/Search/SearchBooksController.swift
@@ -10,9 +10,8 @@ import UIKit
import CoreData
import DZNEmptyDataSet
-class SearchBooksController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, TableCellDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
+class SearchBooksController: SearchTableViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, TableCellDelegate {
- @IBOutlet weak var tableView: UITableView!
@IBOutlet weak var recentSearchContainer: DropShadowView!
@IBOutlet weak var recentSearchBarHeight: NSLayoutConstraint!
@@ -20,9 +19,6 @@ class SearchBooksController: UIViewController, UITableViewDelegate, UITableViewD
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
-// tableView.emptyDataSetSource = self
-// tableView.emptyDataSetDelegate = self
- tableView.tableHeaderView = UIView()
tableView.tableFooterView = UIView()
tableView.keyboardDismissMode = .OnDrag
}
@@ -34,39 +30,12 @@ class SearchBooksController: UIViewController, UITableViewDelegate, UITableViewD
}
func configureRecentSearchBarHeight() {
- let previousHeight = recentSearchBarHeight.constant
let newHeight: CGFloat = Preference.recentSearchTerms.count == 0 ? 0.0 : 44.0
- guard previousHeight != newHeight else {return}
+ guard recentSearchBarHeight.constant != newHeight else {return}
recentSearchBarHeight.constant = newHeight
recentSearchContainer.setNeedsDisplay()
}
- // MARK: - Empty table datasource & delegate
-
- func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
- let text = NSLocalizedString("No Book Available", comment: "Book Library, book downloader, no book center title")
- let attributes = [NSFontAttributeName: UIFont.boldSystemFontOfSize(18.0),
- NSForegroundColorAttributeName: UIColor.darkGrayColor()]
- return NSAttributedString(string: text, attributes: attributes)
- }
-
- func buttonTitleForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> NSAttributedString! {
- let text = NSLocalizedString("Download A Book", comment: "Book Library, book downloader, learn more button text")
- let attributes = [NSFontAttributeName: UIFont.boldSystemFontOfSize(17.0), NSForegroundColorAttributeName: UIButton().tintColor]
- return NSAttributedString(string: text, attributes: attributes)
- }
-
- func verticalOffsetForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
- return -64.0
- }
-
- func spaceHeightForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
- return 0.0
- }
-
- func emptyDataSetDidTapButton(scrollView: UIScrollView!) {
- }
-
// MARK: - Fetched Results Controller
let managedObjectContext = NSManagedObjectContext.mainQueueContext
@@ -185,4 +154,25 @@ class SearchBooksController: UIViewController, UITableViewDelegate, UITableViewD
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
+
+ // MARK: - DZNEmptyDataSet
+
+ func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
+ let string = NSLocalizedString("No Books Available", comment: "Search, Book Selector")
+ let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(18), NSForegroundColorAttributeName: UIColor.darkGrayColor()]
+ return NSAttributedString(string: string, attributes: attributes)
+ }
+
+ func descriptionForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
+ let string = NSLocalizedString("Please download or import a book.", comment: "Search, Book Selector")
+ let paragraph = NSMutableParagraphStyle()
+ paragraph.lineBreakMode = .ByWordWrapping
+ paragraph.alignment = .Center
+ let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(14), NSForegroundColorAttributeName: UIColor.lightGrayColor(), NSParagraphStyleAttributeName: paragraph]
+ return NSAttributedString(string: string, attributes: attributes)
+ }
+
+ func verticalOffsetForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
+ return -(tableView.contentInset.bottom + recentSearchBarHeight.constant) / 2.5
+ }
}
diff --git a/Kiwix-iOS/Controller/Search/SearchController.swift b/Kiwix-iOS/Controller/Search/SearchController.swift
index 51d36d55..f498a1fb 100644
--- a/Kiwix-iOS/Controller/Search/SearchController.swift
+++ b/Kiwix-iOS/Controller/Search/SearchController.swift
@@ -7,6 +7,7 @@
//
import UIKit
+import DZNEmptyDataSet
class SearchController: UIViewController, UISearchBarDelegate, UIGestureRecognizerDelegate {
@@ -81,5 +82,44 @@ class SearchController: UIViewController, UISearchBarDelegate, UIGestureRecogniz
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
return touch.view == view ? true : false
}
-
+}
+
+class SearchTableViewController: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
+ @IBOutlet weak var tableView: UITableView!
+
+ override func viewWillAppear(animated: Bool) {
+ super.viewWillAppear(animated)
+ NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SearchTableViewController.keyboardDidShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
+ NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SearchTableViewController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)
+ }
+
+ override func viewWillDisappear(animated: Bool) {
+ super.viewWillDisappear(animated)
+ tableView.emptyDataSetSource = nil
+ tableView.emptyDataSetDelegate = nil
+ NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
+ NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
+ }
+
+ override func viewDidAppear(animated: Bool) {
+ super.viewDidAppear(animated)
+ tableView.emptyDataSetSource = self
+ tableView.emptyDataSetDelegate = self
+ }
+
+ func keyboardDidShow(notification: NSNotification) {
+ guard let userInfo = notification.userInfo as? [String: NSValue],
+ let origin = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().origin else {return}
+ let point = view.convertPoint(origin, fromView: nil)
+ let buttomInset = view.frame.height - point.y
+ tableView.contentInset = UIEdgeInsetsMake(0.0, 0, buttomInset, 0)
+ tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0, buttomInset, 0)
+ tableView.reloadEmptyDataSet()
+ }
+
+ func keyboardWillHide(notification: NSNotification) {
+ tableView.contentInset = UIEdgeInsetsMake(0.0, 0, 0, 0)
+ tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0, 0, 0)
+ tableView.reloadEmptyDataSet()
+ }
}
diff --git a/Kiwix-iOS/Controller/Search/SearchResultController.swift b/Kiwix-iOS/Controller/Search/SearchResultController.swift
index 53c40ab3..4d8523f7 100644
--- a/Kiwix-iOS/Controller/Search/SearchResultController.swift
+++ b/Kiwix-iOS/Controller/Search/SearchResultController.swift
@@ -8,57 +8,35 @@
import UIKit
import Operations
+import DZNEmptyDataSet
-class SearchResultController: UIViewController, UITableViewDataSource, UITableViewDelegate {
+class SearchResultController: SearchTableViewController, UITableViewDataSource, UITableViewDelegate {
- @IBOutlet weak var tableView: UITableView!
var searchResults = [SearchResult]()
+ var shouldShowNoResults = false
var shouldClipRoundCorner: Bool {
return traitCollection.verticalSizeClass == .Regular && traitCollection.horizontalSizeClass == .Regular
}
+ // MARK: - Override
+
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
tableView.keyboardDismissMode = .OnDrag
+ tableView.emptyDataSetSource = self
+ tableView.emptyDataSetDelegate = self
}
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
- tableView.contentInset = UIEdgeInsetsMake(0.0, 0, 0, 0)
- tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0, 0, 0)
+ guard traitCollection != previousTraitCollection else {return}
tableView.layer.cornerRadius = shouldClipRoundCorner ? 10.0 : 0.0
tableView.layer.masksToBounds = shouldClipRoundCorner
}
- override func viewWillAppear(animated: Bool) {
- super.viewWillAppear(animated)
- tableView.reloadData()
- NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SearchResultController.keyboardDidShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
- NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SearchResultController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)
- }
-
- override func viewWillDisappear(animated: Bool) {
- super.viewWillDisappear(animated)
- searchResults.removeAll()
- NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
- NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
- }
-
- func keyboardDidShow(notification: NSNotification) {
- guard let userInfo = notification.userInfo as? [String: NSValue] else {return}
- guard let keyboardOrigin = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().origin else {return}
- let point = view.convertPoint(keyboardOrigin, fromView: UIApplication.appDelegate.window)
- let buttomInset = view.frame.height - point.y
- tableView.contentInset = UIEdgeInsetsMake(0.0, 0, buttomInset, 0)
- tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0, buttomInset, 0)
- }
-
- func keyboardWillHide(notification: NSNotification) {
- tableView.contentInset = UIEdgeInsetsMake(0.0, 0, 0, 0)
- tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0, 0, 0)
- }
+ // MARK: -
func selectFirstResultIfPossible() {
guard searchResults.count > 0 else {return}
@@ -66,6 +44,40 @@ class SearchResultController: UIViewController, UITableViewDataSource, UITableVi
tableView(tableView, didSelectRowAtIndexPath: NSIndexPath(forRow: 0, inSection: 0))
}
+ func reload(results results: [SearchResult]?) {
+ if let results = results {
+ searchResults = results
+ } else {
+ searchResults.removeAll()
+ }
+
+ tableView.tableFooterView = searchResults.count > 0 ? nil : UIView()
+ tableView.reloadData()
+ tableView.reloadEmptyDataSet()
+
+ guard searchResults.count > 0 else {return}
+ self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
+ }
+
+ func startSearch(searchText: String) {
+ guard searchText != "" else {
+ shouldShowNoResults = false
+ reload(results: nil)
+ return
+ }
+
+ let operation = SearchOperation(searchTerm: searchText)
+ operation.addObserver(DidFinishObserver {(operation, errors) in
+ guard let operation = operation as? SearchOperation else {return}
+ NSOperationQueue.mainQueue().addOperationWithBlock({
+ self.shouldShowNoResults = true
+ self.reload(results: operation.results)
+ })
+ })
+ GlobalQueue.shared.add(search: operation)
+ shouldShowNoResults = false
+ }
+
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
@@ -112,30 +124,26 @@ class SearchResultController: UIViewController, UITableViewDataSource, UITableVi
GlobalQueue.shared.add(load: operation)
}
- // MARK: - Search
+ // MARK: - DZNEmptyDataSet
- func startSearch(searchText: String) {
- guard searchText != "" else {
- searchResults.removeAll()
- tableView.reloadData()
- return
- }
-
- let operation = SearchOperation(searchTerm: searchText)
- operation.addObserver(DidFinishObserver {(operation, errors) in
- guard let operation = operation as? SearchOperation else {return}
- NSOperationQueue.mainQueue().addOperationWithBlock({
- self.searchResults = operation.results
- self.tableView.reloadData()
-
- guard operation.results.count > 0 else {return}
- self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
- })
- })
- GlobalQueue.shared.add(search: operation)
+ func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
+ guard shouldShowNoResults else {return nil}
+ let string = NSLocalizedString("No Results", comment: "Search, Results")
+ let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(18), NSForegroundColorAttributeName: UIColor.darkGrayColor()]
+ return NSAttributedString(string: string, attributes: attributes)
+ }
+
+ func descriptionForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
+ guard shouldShowNoResults else {return nil}
+ let string = NSLocalizedString("Please refine your search term.", comment: "Search, Results")
+ let paragraph = NSMutableParagraphStyle()
+ paragraph.lineBreakMode = .ByWordWrapping
+ paragraph.alignment = .Center
+ let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(14), NSForegroundColorAttributeName: UIColor.lightGrayColor(), NSParagraphStyleAttributeName: paragraph]
+ return NSAttributedString(string: string, attributes: attributes)
+ }
+
+ func verticalOffsetForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
+ return -tableView.contentInset.bottom / 2.5
}
}
-
-extension LocalizedStrings {
- class var searchAddBookGuide: String {return NSLocalizedString("Add a book to get started", comment: "")}
-}
diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist
index b89d7159..202df9c3 100644
--- a/Kiwix-iOS/Info.plist
+++ b/Kiwix-iOS/Info.plist
@@ -49,7 +49,7 @@
CFBundleVersion
- 1.8.1275
+ 1.8.1343
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/Kiwix-iOS/Storyboard/Search.storyboard b/Kiwix-iOS/Storyboard/Search.storyboard
index 261fc30f..8028d5cc 100644
--- a/Kiwix-iOS/Storyboard/Search.storyboard
+++ b/Kiwix-iOS/Storyboard/Search.storyboard
@@ -276,7 +276,7 @@
-
+
diff --git a/Kiwix-iOSWidgets/Bookmarks/Info.plist b/Kiwix-iOSWidgets/Bookmarks/Info.plist
index af0eaaed..59ed41e7 100644
--- a/Kiwix-iOSWidgets/Bookmarks/Info.plist
+++ b/Kiwix-iOSWidgets/Bookmarks/Info.plist
@@ -21,7 +21,7 @@
CFBundleSignature
????
CFBundleVersion
- 1.8.1279
+ 1.8.1347
NSExtension
NSExtensionMainStoryboard
diff --git a/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
index 843ae66a..0b50c5a2 100644
--- a/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+++ b/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -56,7 +56,7 @@
moduleName = "Kiwix"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Volumes/Data/Developer/Kiwix/Kiwix/Operations/BookmarkMigrationOperation.swift"
- timestampString = "496776740.852799"
+ timestampString = "496789129.532637"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "27"
@@ -71,7 +71,7 @@
moduleName = "Kiwix"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Volumes/Data/Developer/Kiwix/Kiwix/Operations/BookmarkMigrationOperation.swift"
- timestampString = "496776740.853959"
+ timestampString = "496789129.534098"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "27"