This commit is contained in:
Chris Li 2017-01-18 14:57:16 -05:00
parent 9b29225b60
commit d119cdf640
5 changed files with 116 additions and 414 deletions

View File

@ -1,249 +0,0 @@
//
// BookmarkController.swift
// Kiwix
//
// Created by Chris Li on 9/27/16.
// Copyright © 2016 Chris Li. All rights reserved.
//
import UIKit
import CoreData
import ProcedureKit
import DZNEmptyDataSet
class BookmarkController: UITableViewController, NSFetchedResultsControllerDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
var book: Book?
var isTopViewController: Bool {
return self == navigationController?.viewControllers.first
}
// MARK: - Overrides
override func viewDidLoad() {
super.viewDidLoad()
title = LocalizedStrings.bookmarks
clearsSelectionOnViewWillAppear = true
tableView.estimatedRowHeight = 66.0
tableView.rowHeight = UITableViewAutomaticDimension
tableView.allowsMultipleSelectionDuringEditing = true
tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self
if isTopViewController {
navigationItem.leftBarButtonItem = UIBarButtonItem(imageNamed: "Cross", target: self, action: #selector(BookmarkController.dismissSelf))
}
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
switch (editing, isTopViewController) {
case (true, true), (true, false):
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(BookmarkController.trashButtonTapped(_:)))
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(BookmarkController.editButtonTapped(_:)))
case (false, true):
navigationItem.leftBarButtonItem = UIBarButtonItem(imageNamed: "Cross", target: self, action: #selector(BookmarkController.dismissSelf))
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(BookmarkController.editButtonTapped(_:)))
case (false, false):
navigationItem.leftBarButtonItem = nil
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(BookmarkController.editButtonTapped(_:)))
}
}
// MARK: - Action
func trash(articles: [Article]) {
let operation = BookmarkTrashOperation(articles: articles)
operation.addObserver(DidFinishObserver { _ in
OperationQueue.mainQueue().addOperationWithBlock({
guard self.fetchedResultController.fetchedObjects?.count == 0 else {return}
self.navigationController?.popViewControllerAnimated(true)
})
})
GlobalQueue.shared.addOperation(operation)
}
func trashButtonTapped(_ sender: UIBarButtonItem) {
guard isEditing else {return}
guard let selectedIndexPathes = tableView.indexPathsForSelectedRows else {return}
let articles = selectedIndexPathes.flatMap() {fetchedResultController.object(at: $0) as? Article}
trash(articles: articles)
}
@IBAction func editButtonTapped(_ sender: UIBarButtonItem) {
setEditing(!isEditing, animated: true)
}
func dismissSelf() {
dismiss(animated: true, completion: nil)
}
// MARK: - Empty table datasource & delegate
func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
return UIImage(named: "BookmarkColor")
}
func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let text = LocalizedStrings.bookmarks
let attributes = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 18.0),
NSForegroundColorAttributeName: UIColor.darkGray]
return NSAttributedString(string: text, attributes: attributes)
}
func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let text = NSLocalizedString("To add a bookmark, long press the star button when reading an article", comment: "Bookmarks view message")
let style = NSMutableParagraphStyle()
style.lineBreakMode = .byWordWrapping
style.alignment = .center
let attributes = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 14.0),
NSForegroundColorAttributeName: UIColor.lightGray,
NSParagraphStyleAttributeName: style]
return NSAttributedString(string: text, attributes: attributes)
}
func spaceHeight(forEmptyDataSet scrollView: UIScrollView!) -> CGFloat {
return 30.0
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultController.sections?.count ?? 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sectionInfo = fetchedResultController.sections?[section] else {return 0}
return sectionInfo.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let article = fetchedResultController.object(at: indexPath) as? Article
if let _ = article?.snippet {
let cell = tableView.dequeueReusableCell(withIdentifier: "BookmarkSnippetCell", for: indexPath)
configureSnippetCell(cell, atIndexPath: indexPath)
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "BookmarkCell", for: indexPath)
configureCell(cell, atIndexPath: indexPath)
return cell
}
}
func configureCell(_ cell: UITableViewCell, atIndexPath indexPath: IndexPath) {
guard let cell = cell as? BookmarkCell else {return}
guard let article = fetchedResultController.object(at: indexPath) as? Article else {return}
cell.thumbImageView.image = {
guard let data = article.thumbImageData else {return nil}
return UIImage(data: data)
}()
cell.titleLabel.text = article.title
cell.subtitleLabel.text = article.book?.title
}
func configureSnippetCell(_ cell: UITableViewCell, atIndexPath indexPath: IndexPath) {
configureCell(cell, atIndexPath: indexPath)
guard let cell = cell as? BookmarkSnippetCell else {return}
guard let article = fetchedResultController.object(at: indexPath) as? Article else {return}
cell.snippetLabel.text = article.snippet
}
// MARK: - Table view delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard !tableView.isEditing else {return}
defer {dismiss(animated: true, completion: nil)}
guard let article = fetchedResultController.object(at: indexPath) as? Article,
let url = article.url else {return}
let operation = ArticleLoadOperation(url: url)
GlobalQueue.shared.add(load: operation)
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {}
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let remove = UITableViewRowAction(style: UITableViewRowActionStyle(), title: LocalizedStrings.remove) { (action, indexPath) -> Void in
guard let article = self.fetchedResultController.object(at: indexPath) as? Article else {return}
let context = NSManagedObjectContext.mainQueueContext
context.performAndWait({ () -> Void in
article.isBookmarked = false
})
self.trash(articles: [article])
}
return [remove]
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
// MARK: - Fetched Result Controller Delegate
let managedObjectContext = NSManagedObjectContext.mainQueueContext
lazy var fetchedResultController: NSFetchedResultsController = { () -> <<error type>> in
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Article")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "bookmarkDate", ascending: false),
NSSortDescriptor(key: "title", ascending: true)]
fetchRequest.predicate = {
if let book = self.book {
return NSPredicate(format: "book = %@ AND isBookmarked = true", book)
} else {
return NSPredicate(format: "isBookmarked = true")
}
}()
let controller = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: self.managedObjectContext,
sectionNameKeyPath: nil,
cacheName: self.book == nil ? nil : "BookmarksFRC" + Bundle.appShortVersion)
controller.delegate = self
controller.performFetch(deleteCache: false)
return controller
}()
// MARK: - Fetched Result Controller Delegate
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
case .delete:
tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
default:
return
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
guard let newIndexPath = newIndexPath else {return}
tableView.insertRows(at: [newIndexPath], with: .left)
case .delete:
guard let indexPath = indexPath else {return}
tableView.deleteRows(at: [indexPath], with: .right)
case .update:
guard let indexPath = indexPath, let cell = tableView.cellForRow(at: indexPath) else {return}
configureCell(cell, atIndexPath: indexPath)
case .move:
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {return}
tableView.deleteRows(at: [indexPath], with: .right)
tableView.insertRows(at: [newIndexPath], with: .left)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
}

View File

@ -1,44 +0,0 @@
//
// BookmarkSplitController.swift
// Kiwix
//
// Created by Chris Li on 1/12/17.
// Copyright © 2017 Chris Li. All rights reserved.
//
import UIKit
class BookmarkSplitController: UISplitViewController, UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
preferredDisplayMode = .allVisible
minimumPrimaryColumnWidth = 320.0
delegate = self
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
guard traitCollection != previousTraitCollection else {return}
let controller: CoreDataTableBaseController? = {
let nav = viewControllers.first as? UINavigationController
return nav?.topViewController as? CoreDataTableBaseController
}()
controller?.tableView.indexPathsForVisibleRows?.forEach({ (indexPath) in
guard let cell = controller?.tableView.cellForRow(at: indexPath) else {return}
controller?.configureCell(cell, atIndexPath: indexPath)
})
}
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
if let nav = secondaryViewController as? UINavigationController,
let controller = nav.topViewController as? BookmarkCollectionController,
let _ = controller.book {
// show detail
return false
} else {
// show master
return true
}
}
}

View File

@ -0,0 +1,95 @@
//
// SettingsController.swift
// Kiwix
//
// Created by Chris Li on 1/18/17.
// Copyright © 2017 Chris Li. All rights reserved.
//
import UIKit
class SettingsController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
/*
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
return cell
}
*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

View File

@ -6,6 +6,7 @@
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
@ -35,7 +36,7 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Cell" id="lfi-9s-ZjZ" customClass="BookmarkCollectionCell" customModule="Kiwix" customModuleProvider="target">
<rect key="frame" x="103.66666666666667" y="0.0" width="207" height="169"/>
<rect key="frame" x="104" y="0.0" width="207" height="169"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="207" height="169"/>
@ -168,79 +169,6 @@
</objects>
<point key="canvasLocation" x="5005.7971014492759" y="3266.576086956522"/>
</scene>
<!--Bookmark Article Controller-->
<scene sceneID="VN9-Ad-dWZ">
<objects>
<viewController id="xE4-gI-XU7" customClass="BookmarkArticleController" customModule="Kiwix" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="KsU-SN-Q6B"/>
<viewControllerLayoutGuide type="bottom" id="i96-VK-hQ6"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Xiw-sf-MU8">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Qeu-f3-5WZ">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="PgF-nn-SRl" style="IBUITableViewCellStyleDefault" id="ctR-1A-5o0">
<rect key="frame" x="0.0" y="28" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ctR-1A-5o0" id="5Nd-fl-Nsl">
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="PgF-nn-SRl">
<rect key="frame" x="15" y="0.0" width="384" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="xE4-gI-XU7" id="Lkk-BR-5CV"/>
<outlet property="delegate" destination="xE4-gI-XU7" id="cZz-Kc-ooY"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="Qeu-f3-5WZ" firstAttribute="top" secondItem="Xiw-sf-MU8" secondAttribute="top" id="2cO-aT-bsr"/>
<constraint firstItem="i96-VK-hQ6" firstAttribute="top" secondItem="Qeu-f3-5WZ" secondAttribute="bottom" id="MuY-3z-cYR"/>
<constraint firstItem="Qeu-f3-5WZ" firstAttribute="leading" secondItem="Xiw-sf-MU8" secondAttribute="leading" id="YR8-76-eRf"/>
<constraint firstAttribute="trailing" secondItem="Qeu-f3-5WZ" secondAttribute="trailing" id="oQ7-ZW-ApC"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="UYE-OB-ou5"/>
<connections>
<outlet property="tableView" destination="Qeu-f3-5WZ" id="BuJ-5o-bhv"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="KyR-qJ-SWv" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2706" y="2413"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="i96-PS-3ib">
<objects>
<navigationController id="8sg-ud-siF" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="THl-YC-SF3">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="6ta-bG-bwf" kind="relationship" relationship="rootViewController" id="00r-M0-WcP"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="KtC-fm-L5w" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1843" y="1769"/>
</scene>
<!--Bookmark Books Controller-->
<scene sceneID="g5J-tc-3iG">
<objects>
@ -258,10 +186,10 @@
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" id="ZwJ-s2-oXZ" customClass="BasicBookCell" customModule="Kiwix" customModuleProvider="target">
<rect key="frame" x="0.0" y="55.333333333333336" width="414" height="44"/>
<rect key="frame" x="0.0" y="56" width="414" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ZwJ-s2-oXZ" id="acz-8H-Je1">
<rect key="frame" x="0.0" y="0.0" width="381" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="381" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" minimumFontSize="8" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F5J-kg-p5Y">
@ -323,7 +251,6 @@
<outlet property="hasPicIndicator" destination="vCd-Vo-NUE" id="oxG-mF-2gO"/>
<outlet property="subtitleLabel" destination="wUN-Co-X2K" id="tJG-Vg-Ctp"/>
<outlet property="titleLabel" destination="F5J-kg-p5Y" id="SGC-oq-RQ6"/>
<segue destination="hDm-kh-ZLk" kind="showDetail" identifier="showBookmarks" id="vG1-Ih-Ag7"/>
</connections>
</tableViewCell>
</prototypes>
@ -354,20 +281,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Mda-Cj-fak" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2706" y="1769"/>
</scene>
<!--Bookmark Split Controller-->
<scene sceneID="SDm-nf-Wpq">
<objects>
<splitViewController id="ALQ-3b-cEW" customClass="BookmarkSplitController" customModule="Kiwix" customModuleProvider="target" sceneMemberID="viewController">
<connections>
<segue destination="8sg-ud-siF" kind="relationship" relationship="masterViewController" id="25F-nw-ITK"/>
<segue destination="hDm-kh-ZLk" kind="relationship" relationship="detailViewController" id="ipW-qc-ph3"/>
</connections>
</splitViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="XnC-Pf-fz7" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="928" y="2095"/>
<point key="canvasLocation" x="5006" y="2565"/>
</scene>
<!--BookmarkHUD-->
<scene sceneID="eMu-pk-jX5">
@ -488,24 +402,6 @@
<point key="canvasLocation" x="4099" y="2566"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="IbQ-Ft-djH">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="hDm-kh-ZLk" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="lNg-T6-EiE">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="xE4-gI-XU7" kind="relationship" relationship="rootViewController" id="4H6-ag-m1c"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="avJ-P8-fSY" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1843" y="2414"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="DnL-5M-iZu">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="ogU-eE-4Z9" sceneMemberID="viewController">
@ -531,7 +427,4 @@
<image name="Cross" width="16" height="16"/>
<image name="Dots" width="21" height="21"/>
</resources>
<inferredMetricsTieBreakers>
<segue reference="ipW-qc-ph3"/>
</inferredMetricsTieBreakers>
</document>

View File

@ -64,7 +64,6 @@
9757C74A1E10660B008A9469 /* DownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9757C7491E10660B008A9469 /* DownloadManager.swift */; };
9757C74C1E106958008A9469 /* BackgroundDownload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9757C74B1E106958008A9469 /* BackgroundDownload.swift */; };
97599AA21E26D3B000BA15EF /* BookmarkBooksController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97599AA11E26D3B000BA15EF /* BookmarkBooksController.swift */; };
97599AE01E28031A00BA15EF /* BookmarkSplitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97599ADF1E28031A00BA15EF /* BookmarkSplitController.swift */; };
97599AE21E28193D00BA15EF /* BookmarkCollectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97599AE11E28193D00BA15EF /* BookmarkCollectionController.swift */; };
975B90FE1CEB909100D13906 /* iOSExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975B90FD1CEB909100D13906 /* iOSExtensions.swift */; };
9764CBD11D806AD800072D6A /* RefreshLibControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764CBD01D806AD800072D6A /* RefreshLibControl.swift */; };
@ -72,6 +71,7 @@
9764F5991D833F2B00E0B1C4 /* KiwixURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764F5981D833F2B00E0B1C4 /* KiwixURL.swift */; };
976B86D81DDA0C7E00FA7FD1 /* SearchContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976B86D71DDA0C7E00FA7FD1 /* SearchContainer.swift */; };
976C1DCB1E2FD5FC005EDEC4 /* TableOfContentsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976C1DCA1E2FD5FC005EDEC4 /* TableOfContentsController.swift */; };
976C1DCE1E30000E005EDEC4 /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976C1DCD1E30000E005EDEC4 /* SettingsController.swift */; };
9771A5BD1DD269BD005F1795 /* Book+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D6813C1D6F712800E5FA99 /* Book+CoreDataProperties.swift */; };
9779C3141D4575AD0064CC8E /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97E609F01D103DED00EBCB9D /* NotificationCenter.framework */; };
9779C3171D4575AE0064CC8E /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9779C3161D4575AE0064CC8E /* TodayViewController.swift */; };
@ -223,7 +223,6 @@
9757C7491E10660B008A9469 /* DownloadManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadManager.swift; sourceTree = "<group>"; };
9757C74B1E106958008A9469 /* BackgroundDownload.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundDownload.swift; sourceTree = "<group>"; };
97599AA11E26D3B000BA15EF /* BookmarkBooksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkBooksController.swift; sourceTree = "<group>"; };
97599ADF1E28031A00BA15EF /* BookmarkSplitController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkSplitController.swift; sourceTree = "<group>"; };
97599AE11E28193D00BA15EF /* BookmarkCollectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkCollectionController.swift; sourceTree = "<group>"; };
975B90FD1CEB909100D13906 /* iOSExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = iOSExtensions.swift; path = "Kiwix-iOS/iOSExtensions.swift"; sourceTree = SOURCE_ROOT; };
9763275D1D64FE0F0034F120 /* BookDetailController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookDetailController.swift; sourceTree = "<group>"; };
@ -234,6 +233,7 @@
976A0C801D41619C0006A742 /* DZNEmptyDataSet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DZNEmptyDataSet.framework; path = "../../../../Users/chrisli/Library/Developer/Xcode/DerivedData/Kiwix-ayxrfhaqnfxzendihdolvkklkmhk/Build/Products/Debug-iphoneos/DZNEmptyDataSet/DZNEmptyDataSet.framework"; sourceTree = "<group>"; };
976B86D71DDA0C7E00FA7FD1 /* SearchContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchContainer.swift; sourceTree = "<group>"; };
976C1DCA1E2FD5FC005EDEC4 /* TableOfContentsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableOfContentsController.swift; sourceTree = "<group>"; };
976C1DCD1E30000E005EDEC4 /* SettingsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
9779C3131D4575AD0064CC8E /* Bookmarks.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Bookmarks.appex; sourceTree = BUILT_PRODUCTS_DIR; };
9779C3161D4575AE0064CC8E /* TodayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewController.swift; sourceTree = "<group>"; };
9779C31B1D4575AE0064CC8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -272,7 +272,6 @@
97C005D51D64B3B0004352E8 /* Library.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Library.storyboard; path = "Kiwix-iOS/Storyboard/Library.storyboard"; sourceTree = SOURCE_ROOT; };
97C005D71D64B99E004352E8 /* LibrarySplitViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LibrarySplitViewController.swift; path = "Kiwix-iOS/Controller/Library/LibrarySplitViewController.swift"; sourceTree = SOURCE_ROOT; };
97C005DB1D64BEFE004352E8 /* CloudBooksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudBooksController.swift; sourceTree = "<group>"; };
97C5BD4A1D9AF4B5009692CF /* BookmarkController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkController.swift; sourceTree = "<group>"; };
97C601DB1D7F15C400362D4F /* Bookmark.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Bookmark.storyboard; sourceTree = "<group>"; };
97C601DD1D7F342100362D4F /* HTMLHeading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLHeading.swift; sourceTree = "<group>"; };
97D0E9921DDA487E0029530E /* SearchBaseController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBaseController.swift; sourceTree = "<group>"; };
@ -535,9 +534,7 @@
isa = PBXGroup;
children = (
97599AE11E28193D00BA15EF /* BookmarkCollectionController.swift */,
97599ADF1E28031A00BA15EF /* BookmarkSplitController.swift */,
97599AA11E26D3B000BA15EF /* BookmarkBooksController.swift */,
97C5BD4A1D9AF4B5009692CF /* BookmarkController.swift */,
97219DBC1D383A00009FDFF1 /* BookmarkHUD.swift */,
);
path = Bookmark;
@ -588,7 +585,7 @@
name = Others;
sourceTree = "<group>";
};
9771DC4B1C37278E009ECFF0 /* Setting */ = {
976C1DCC1E2FFFF3005EDEC4 /* old */ = {
isa = PBXGroup;
children = (
970E7F761D9DBEA900741290 /* SettingController.swift */,
@ -596,6 +593,16 @@
973DD4271D36E3E4009D45DB /* SettingDetailController.swift */,
970E7F781DA003FA00741290 /* WebViewControllerOld.swift */,
);
name = old;
sourceTree = "<group>";
};
9771DC4B1C37278E009ECFF0 /* Setting */ = {
isa = PBXGroup;
children = (
9787BC1F1D9318080030D311 /* Others */,
976C1DCC1E2FFFF3005EDEC4 /* old */,
976C1DCD1E30000E005EDEC4 /* SettingsController.swift */,
);
path = Setting;
sourceTree = "<group>";
};
@ -625,7 +632,8 @@
973A5C911DEA3F5600C7804C /* CoreDataTableBaseController.swift */,
970E7F7F1DA0305000741290 /* WelcomeController.swift */,
);
path = Others;
name = Others;
path = ../Others;
sourceTree = "<group>";
};
978C587A1C1CCC9C0077AE47 /* Storyboards */ = {
@ -650,7 +658,6 @@
972B007D1C35DBAB00B5FDC5 /* Main */,
97E108221C5D5A0D00E27FD3 /* Search */,
9771DC4B1C37278E009ECFF0 /* Setting */,
9787BC1F1D9318080030D311 /* Others */,
);
name = Controllers;
path = Controller;
@ -1090,6 +1097,7 @@
973207A51DD1984700EDD3DC /* SearchScopeAndHistoryController.swift in Sources */,
973207A21DD1983D00EDD3DC /* BookDetailController.swift in Sources */,
973208231DD19C7600EDD3DC /* DownloadProgress.swift in Sources */,
976C1DCE1E30000E005EDEC4 /* SettingsController.swift in Sources */,
97A1FD161D6F71CE00A80EE2 /* DirectoryMonitor.swift in Sources */,
9726591D1D90A64600D1DFFB /* Notifications.swift in Sources */,
971A102C1D022AD5007FC62C /* BarButtonItems.swift in Sources */,
@ -1140,7 +1148,6 @@
97A1FD191D6F71CE00A80EE2 /* ZimMultiReader.swift in Sources */,
97A1FD261D6F71E200A80EE2 /* ZimReader.mm in Sources */,
97A1FD1C1D6F71D800A80EE2 /* KiwixURLProtocol.swift in Sources */,
97599AE01E28031A00BA15EF /* BookmarkSplitController.swift in Sources */,
97C2C26A1DDCC58500A9CC64 /* ArticleOperation.swift in Sources */,
973A5C991DEBC54800C7804C /* CloudKit.swift in Sources */,
973208261DD21E9C00EDD3DC /* CoreDataContainer.swift in Sources */,