mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-26 05:18:31 -04:00
Bookmark collection fetched result controller
This commit is contained in:
parent
b9e01de6fc
commit
baf4cf4c4e
@ -9,11 +9,22 @@
|
||||
import UIKit
|
||||
import CoreData
|
||||
|
||||
class BookmarkCollectionController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout,NSFetchedResultsControllerDelegate {
|
||||
class BookmarkCollectionController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, NSFetchedResultsControllerDelegate {
|
||||
|
||||
private(set) var itemWidth: CGFloat = 0.0
|
||||
private(set) var shouldReloadCollectionView = false
|
||||
@IBOutlet weak var collectionView: UICollectionView!
|
||||
@IBAction func removaAll(_ sender: UIBarButtonItem) {
|
||||
let context = AppDelegate.persistentContainer.viewContext
|
||||
context.perform {
|
||||
let fetchRequest = Article.fetchRequest() as! NSFetchRequest<Article>
|
||||
let articles = try? context.fetch(fetchRequest)
|
||||
articles?.forEach({ (article) in
|
||||
context.delete(article)
|
||||
})
|
||||
try? context.save()
|
||||
}
|
||||
}
|
||||
|
||||
var book: Book? {
|
||||
didSet {
|
||||
@ -26,7 +37,7 @@ class BookmarkCollectionController: UIViewController, UICollectionViewDataSource
|
||||
}
|
||||
|
||||
func configureItemWidth(collectionViewWidth: CGFloat) {
|
||||
let itemsPerRow = ((collectionViewWidth - 10) / 300).rounded()
|
||||
let itemsPerRow = ((collectionViewWidth - 10) / 320).rounded()
|
||||
self.itemWidth = floor((collectionViewWidth - (itemsPerRow + 1) * 10) / itemsPerRow)
|
||||
}
|
||||
|
||||
@ -62,33 +73,36 @@ class BookmarkCollectionController: UIViewController, UICollectionViewDataSource
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell2", for: indexPath) as! BookmarkCollectionCell
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! BookmarkCollectionCell
|
||||
let article = fetchedResultController.object(at: indexPath)
|
||||
cell.titleLabel.text = article.title
|
||||
cell.snippetLabel.text = article.snippet
|
||||
// cell.thumbImageView.image
|
||||
if let data = article.thumbImageData {
|
||||
cell.thumbImageView.image = UIImage(data: data)
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDelegateFlowLayout
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||
return CGSize(width: itemWidth, height: itemWidth)
|
||||
return CGSize(width: itemWidth, height: itemWidth * 0.72)
|
||||
}
|
||||
|
||||
// MARK: - NSFetchedResultsControllerDelegate
|
||||
// MARK: - NSFetchedResultsController
|
||||
|
||||
var blocks = [() -> Void]()
|
||||
var blockOperations: [BlockOperation] = []
|
||||
private var closures = [() -> Void]()
|
||||
let managedObjectContext = AppDelegate.persistentContainer.viewContext
|
||||
lazy var fetchedResultController: NSFetchedResultsController<Article> = {
|
||||
let fetchRequest = Article.fetchRequest()
|
||||
let titleDescriptor = NSSortDescriptor(key: "title", ascending: true)
|
||||
fetchRequest.sortDescriptors = [titleDescriptor]
|
||||
if let book = self.book {fetchRequest.predicate = NSPredicate(format: "book == %@", book)}
|
||||
|
||||
let cacheName = ["BookmarkFRC", self.book?.title ?? "All", Bundle.buildVersion].joined(separator: "_")
|
||||
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: cacheName)
|
||||
// var predicates = [NSPredicate]()
|
||||
// predicates.append(NSPredicate(format: "isBookmarked = true"))
|
||||
// if let book = self.book { predicates.append(NSPredicate(format: "book == %@", book)) }
|
||||
// fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
|
||||
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
|
||||
controller.delegate = self
|
||||
try? controller.performFetch()
|
||||
return controller as! NSFetchedResultsController<Article>
|
||||
@ -103,33 +117,32 @@ class BookmarkCollectionController: UIViewController, UICollectionViewDataSource
|
||||
shouldReloadCollectionView = true
|
||||
break
|
||||
}
|
||||
blocks.append({ self.collectionView.insertItems(at: [newIndexPath]) })
|
||||
closures.append({ [weak self] in self?.collectionView.insertItems(at: [newIndexPath]) })
|
||||
case .delete:
|
||||
guard let indexPath = indexPath else {break}
|
||||
blocks.append({ self.collectionView.reloadItems(at: [indexPath]) })
|
||||
closures.append({ [weak self] in self?.collectionView.deleteItems(at: [indexPath]) })
|
||||
case .move:
|
||||
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {break}
|
||||
blocks.append({ self.collectionView.moveItem(at: indexPath, to: newIndexPath) })
|
||||
closures.append({ [weak self] in self?.collectionView.moveItem(at: indexPath, to: newIndexPath) })
|
||||
case .update:
|
||||
guard let indexPath = indexPath, collectionView.numberOfItems(inSection: indexPath.section) != 1 else {
|
||||
self.shouldReloadCollectionView = true
|
||||
break
|
||||
}
|
||||
blocks.append({ self.collectionView.deleteItems(at: [indexPath]) })
|
||||
closures.append({ [weak self] in self?.collectionView.reloadItems(at: [indexPath]) })
|
||||
}
|
||||
}
|
||||
|
||||
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
|
||||
|
||||
switch type {
|
||||
case .insert:
|
||||
blocks.append({ self.collectionView.insertSections(IndexSet(integer: sectionIndex)) })
|
||||
closures.append({ [weak self] in self?.collectionView.insertSections(IndexSet(integer: sectionIndex)) })
|
||||
case .delete:
|
||||
blocks.append({ self.collectionView.deleteSections(IndexSet(integer: sectionIndex)) })
|
||||
closures.append({ [weak self] in self?.collectionView.deleteSections(IndexSet(integer: sectionIndex)) })
|
||||
case .move:
|
||||
break
|
||||
case .update:
|
||||
blocks.append({ self.collectionView.reloadSections(IndexSet(integer: sectionIndex)) })
|
||||
closures.append({ [weak self] in self?.collectionView.reloadSections(IndexSet(integer: sectionIndex)) })
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,9 +152,9 @@ class BookmarkCollectionController: UIViewController, UICollectionViewDataSource
|
||||
self.collectionView.reloadData()
|
||||
} else {
|
||||
self.collectionView.performBatchUpdates({
|
||||
self.blocks.forEach({ $0() })
|
||||
self.closures.forEach({ $0() })
|
||||
}, completion: { (completed) in
|
||||
self.blocks.removeAll()
|
||||
self.closures.removeAll()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -34,43 +34,21 @@
|
||||
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="Cell2" id="Qh9-Dg-cx2" customClass="BookmarkCollectionCell2" customModule="Kiwix" customModuleProvider="target">
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="HlJ-Gh-ypg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="207" height="169"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="HlJ-Gh-ypg" secondAttribute="bottom" id="XNJ-UB-503"/>
|
||||
<constraint firstAttribute="trailing" secondItem="HlJ-Gh-ypg" secondAttribute="trailing" id="YMT-pX-wS0"/>
|
||||
<constraint firstItem="HlJ-Gh-ypg" firstAttribute="leading" secondItem="Qh9-Dg-cx2" secondAttribute="leading" id="Yzl-2O-HbG"/>
|
||||
<constraint firstItem="HlJ-Gh-ypg" firstAttribute="top" secondItem="Qh9-Dg-cx2" secondAttribute="top" id="k0W-oo-MeX"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="thumbImageView" destination="HlJ-Gh-ypg" id="PGR-cg-qZH"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
<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="104" y="179" width="207" height="169"/>
|
||||
<rect key="frame" x="103.66666666666667" 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"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="CQi-0M-O0e">
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="CQi-0M-O0e">
|
||||
<rect key="frame" x="8" y="129" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="3bz-bb-cig"/>
|
||||
<constraint firstAttribute="width" constant="32" id="aFo-L8-O71"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LK0-aY-C9L">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="justified" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LK0-aY-C9L">
|
||||
<rect key="frame" x="8" y="29" width="191" height="17"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
@ -86,14 +64,14 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9EM-Do-qfE">
|
||||
<rect key="frame" x="8" y="124" width="191" height="2"/>
|
||||
<rect key="frame" x="8" y="123" width="191" height="2"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="2" id="y4a-qe-lIJ"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Alw-Di-WEl">
|
||||
<rect key="frame" x="48" y="128" width="31" height="13.333333333333343"/>
|
||||
<rect key="frame" x="48" y="126.99999999999999" width="31" height="14.666666666666643"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@ -108,10 +86,10 @@
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="9EM-Do-qfE" secondAttribute="trailing" id="0H3-5k-m0f"/>
|
||||
<constraint firstItem="LK0-aY-C9L" firstAttribute="top" secondItem="YA4-yb-hoI" secondAttribute="bottom" id="95I-Gx-tc1"/>
|
||||
<constraint firstItem="CQi-0M-O0e" firstAttribute="top" secondItem="9EM-Do-qfE" secondAttribute="bottom" constant="3" id="9jg-Ou-dzI"/>
|
||||
<constraint firstItem="CQi-0M-O0e" firstAttribute="top" secondItem="9EM-Do-qfE" secondAttribute="bottom" constant="4" id="9jg-Ou-dzI"/>
|
||||
<constraint firstItem="Alw-Di-WEl" firstAttribute="leading" secondItem="CQi-0M-O0e" secondAttribute="trailing" constant="8" id="Eoq-GI-7la"/>
|
||||
<constraint firstItem="Alw-Di-WEl" firstAttribute="top" secondItem="9EM-Do-qfE" secondAttribute="bottom" constant="2" id="GkX-zd-iqc"/>
|
||||
<constraint firstItem="9EM-Do-qfE" firstAttribute="top" relation="greaterThanOrEqual" secondItem="LK0-aY-C9L" secondAttribute="bottom" id="Hju-Lg-iT1"/>
|
||||
<constraint firstItem="9EM-Do-qfE" firstAttribute="top" relation="greaterThanOrEqual" secondItem="LK0-aY-C9L" secondAttribute="bottom" constant="4" id="Hju-Lg-iT1"/>
|
||||
<constraint firstItem="YA4-yb-hoI" firstAttribute="top" secondItem="lfi-9s-ZjZ" secondAttribute="topMargin" id="MCl-Il-92w"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="HLG-V7-emv" secondAttribute="bottom" id="MLR-CH-oRZ"/>
|
||||
<constraint firstItem="LK0-aY-C9L" firstAttribute="trailing" secondItem="lfi-9s-ZjZ" secondAttribute="trailingMargin" id="Uyi-Wf-Cnt"/>
|
||||
@ -150,6 +128,11 @@
|
||||
<action selector="dismiss:" destination="mMM-mS-I3F" id="PkU-Qf-DQ9"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="trash" id="ELs-vA-7OD">
|
||||
<connections>
|
||||
<action selector="removaAll:" destination="mMM-mS-I3F" id="LC1-Lp-IK5"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="collectionView" destination="Nlm-HS-W5q" id="nxj-xO-4Py"/>
|
||||
@ -249,10 +232,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">
|
||||
@ -278,7 +261,7 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vCd-Vo-NUE">
|
||||
<rect key="frame" x="42" y="6" width="2" height="32"/>
|
||||
<rect key="frame" x="42" y="6" width="2" height="31"/>
|
||||
<color key="backgroundColor" red="1" green="0.40000000000000002" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="2" id="mUe-cP-6T5"/>
|
||||
|
@ -93,36 +93,17 @@ class CheckMarkBookCell: BasicBookCell {
|
||||
|
||||
// MARK: - Article Cell
|
||||
|
||||
class BookmarkCollectionCell: UICollectionViewCell {
|
||||
override func awakeFromNib() {
|
||||
clipsToBounds = false
|
||||
backgroundColor = UIColor.clear
|
||||
layer.masksToBounds = false
|
||||
layer.shadowColor = UIColor.lightGray.cgColor
|
||||
layer.shadowOpacity = 0.5
|
||||
layer.shadowOffset = CGSize.zero
|
||||
layer.shadowRadius = 1.0
|
||||
|
||||
contentView.clipsToBounds = true
|
||||
contentView.backgroundColor = UIColor.white
|
||||
contentView.layer.masksToBounds = true
|
||||
contentView.layer.cornerRadius = 2.0
|
||||
|
||||
thumbImageView.layer.cornerRadius = 4.0
|
||||
thumbImageView.clipsToBounds = true
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: 2.0).cgPath
|
||||
}
|
||||
|
||||
@IBOutlet weak var thumbImageView: UIImageView!
|
||||
class ArticleCell: FavIconAndPicIndicatorCell {
|
||||
@IBOutlet weak var titleLabel: UILabel!
|
||||
}
|
||||
|
||||
class ArticleSnippetCell: ArticleCell {
|
||||
@IBOutlet weak var snippetLabel: UILabel!
|
||||
}
|
||||
|
||||
class BookmarkCollectionCell2: UICollectionViewCell {
|
||||
// MARK: - Bookmark Cell
|
||||
|
||||
class BookmarkCollectionCell: UICollectionViewCell {
|
||||
override func awakeFromNib() {
|
||||
clipsToBounds = false
|
||||
backgroundColor = UIColor.clear
|
||||
|
@ -71,7 +71,7 @@ function Snippet () {
|
||||
for (i = 0; i < elements.length; i++) {
|
||||
var localSnippet = this.extractCleanText(elements[i]);
|
||||
snippet += localSnippet;
|
||||
if (snippet.length > 200) {break;}
|
||||
if (snippet.length > 400) {break;}
|
||||
}
|
||||
return snippet;
|
||||
}
|
||||
@ -89,4 +89,4 @@ function Snippet () {
|
||||
}
|
||||
|
||||
var tableOfContents = new TableOfContents();
|
||||
var snippet = new Snippet();
|
||||
var snippet = new Snippet();
|
||||
|
Loading…
x
Reference in New Issue
Block a user