Add item cell
This commit is contained in:
parent
8d385e61f5
commit
dd71c06257
|
@ -40,6 +40,8 @@
|
||||||
D6E2435E278B97240005E546 /* Item+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E2435A278B97240005E546 /* Item+CoreDataProperties.swift */; };
|
D6E2435E278B97240005E546 /* Item+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E2435A278B97240005E546 /* Item+CoreDataProperties.swift */; };
|
||||||
D6E2435F278B97240005E546 /* Group+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E2435B278B97240005E546 /* Group+CoreDataClass.swift */; };
|
D6E2435F278B97240005E546 /* Group+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E2435B278B97240005E546 /* Group+CoreDataClass.swift */; };
|
||||||
D6E24360278B97240005E546 /* Group+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E2435C278B97240005E546 /* Group+CoreDataProperties.swift */; };
|
D6E24360278B97240005E546 /* Group+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E2435C278B97240005E546 /* Group+CoreDataProperties.swift */; };
|
||||||
|
D6E24363278BA1410005E546 /* ItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E24361278BA1410005E546 /* ItemCollectionViewCell.swift */; };
|
||||||
|
D6E24367278BA2660005E546 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = D6E24366278BA2660005E546 /* SwiftSoup */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -117,6 +119,7 @@
|
||||||
D6E2435A278B97240005E546 /* Item+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Item+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
D6E2435A278B97240005E546 /* Item+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Item+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
D6E2435B278B97240005E546 /* Group+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Group+CoreDataClass.swift"; sourceTree = "<group>"; };
|
D6E2435B278B97240005E546 /* Group+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Group+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
D6E2435C278B97240005E546 /* Group+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Group+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
D6E2435C278B97240005E546 /* Group+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Group+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
|
D6E24361278BA1410005E546 /* ItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -125,6 +128,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
D6C68829272CD2BA00874C10 /* Fervor.framework in Frameworks */,
|
D6C68829272CD2BA00874C10 /* Fervor.framework in Frameworks */,
|
||||||
|
D6E24367278BA2660005E546 /* SwiftSoup in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -270,6 +274,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D6E2434B278B456A0005E546 /* ItemsViewController.swift */,
|
D6E2434B278B456A0005E546 /* ItemsViewController.swift */,
|
||||||
|
D6E24361278BA1410005E546 /* ItemCollectionViewCell.swift */,
|
||||||
);
|
);
|
||||||
path = Items;
|
path = Items;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -303,6 +308,9 @@
|
||||||
D6C68828272CD2BA00874C10 /* PBXTargetDependency */,
|
D6C68828272CD2BA00874C10 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Reader;
|
name = Reader;
|
||||||
|
packageProductDependencies = (
|
||||||
|
D6E24366278BA2660005E546 /* SwiftSoup */,
|
||||||
|
);
|
||||||
productName = Reader;
|
productName = Reader;
|
||||||
productReference = D6C687E8272CD27600874C10 /* Reader.app */;
|
productReference = D6C687E8272CD27600874C10 /* Reader.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
|
@ -397,6 +405,9 @@
|
||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
mainGroup = D6C687DF272CD27600874C10;
|
mainGroup = D6C687DF272CD27600874C10;
|
||||||
|
packageReferences = (
|
||||||
|
D6E24365278BA2660005E546 /* XCRemoteSwiftPackageReference "SwiftSoup" */,
|
||||||
|
);
|
||||||
productRefGroup = D6C687E9272CD27600874C10 /* Products */;
|
productRefGroup = D6C687E9272CD27600874C10 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
|
@ -460,6 +471,7 @@
|
||||||
D6E24358278B96E40005E546 /* Feed+CoreDataProperties.swift in Sources */,
|
D6E24358278B96E40005E546 /* Feed+CoreDataProperties.swift in Sources */,
|
||||||
D65B18BE275051A1004A9448 /* LocalData.swift in Sources */,
|
D65B18BE275051A1004A9448 /* LocalData.swift in Sources */,
|
||||||
D65B18B22750469D004A9448 /* LoginViewController.swift in Sources */,
|
D65B18B22750469D004A9448 /* LoginViewController.swift in Sources */,
|
||||||
|
D6E24363278BA1410005E546 /* ItemCollectionViewCell.swift in Sources */,
|
||||||
D65B18C127505348004A9448 /* HomeViewController.swift in Sources */,
|
D65B18C127505348004A9448 /* HomeViewController.swift in Sources */,
|
||||||
D6C687EE272CD27600874C10 /* SceneDelegate.swift in Sources */,
|
D6C687EE272CD27600874C10 /* SceneDelegate.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
@ -896,6 +908,25 @@
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
D6E24365278BA2660005E546 /* XCRemoteSwiftPackageReference "SwiftSoup" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/scinfu/SwiftSoup";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMinorVersion;
|
||||||
|
minimumVersion = 2.3.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
D6E24366278BA2660005E546 /* SwiftSoup */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = D6E24365278BA2660005E546 /* XCRemoteSwiftPackageReference "SwiftSoup" */;
|
||||||
|
productName = SwiftSoup;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
D6C687F4272CD27600874C10 /* Reader.xcdatamodeld */ = {
|
D6C687F4272CD27600874C10 /* Reader.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
//
|
||||||
|
// ItemCollectionViewCell.swift
|
||||||
|
// Reader
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 1/9/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SwiftSoup
|
||||||
|
|
||||||
|
class ItemCollectionViewCell: UICollectionViewCell {
|
||||||
|
|
||||||
|
private let titleLabel = UILabel()
|
||||||
|
private let feedTitleLabel = UILabel()
|
||||||
|
private let contentLabel = UILabel()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .title3).withSymbolicTraits(.traitBold)!.withDesign(.serif)!
|
||||||
|
titleLabel.font = UIFont(descriptor: descriptor, size: 0)
|
||||||
|
titleLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
feedTitleLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .subheadline), size: 0)
|
||||||
|
feedTitleLabel.textColor = .tintColor
|
||||||
|
|
||||||
|
contentLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .body).withDesign(.serif)!, size: 0)
|
||||||
|
contentLabel.textColor = UIColor(dynamicProvider: { traitCollection in
|
||||||
|
if traitCollection.userInterfaceStyle == .dark {
|
||||||
|
return .lightGray
|
||||||
|
} else {
|
||||||
|
return .darkGray
|
||||||
|
}
|
||||||
|
})
|
||||||
|
contentLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
let stack = UIStackView(arrangedSubviews: [
|
||||||
|
titleLabel,
|
||||||
|
feedTitleLabel,
|
||||||
|
contentLabel,
|
||||||
|
])
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
stack.spacing = 8
|
||||||
|
stack.axis = .vertical
|
||||||
|
addSubview(stack)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
stack.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
|
||||||
|
stack.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20),
|
||||||
|
stack.topAnchor.constraint(equalTo: topAnchor, constant: 8),
|
||||||
|
stack.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUI(item: Item) {
|
||||||
|
titleLabel.text = item.title
|
||||||
|
feedTitleLabel.text = item.feed!.title ?? item.feed!.url?.host
|
||||||
|
if let content = item.content {
|
||||||
|
let doc = try! SwiftSoup.parse(content)
|
||||||
|
contentLabel.text = try! doc.select("p").first()?.text()
|
||||||
|
} else {
|
||||||
|
contentLabel.text = ""
|
||||||
|
}
|
||||||
|
contentLabel.isHidden = contentLabel.text?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ class ItemsViewController: UIViewController {
|
||||||
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
|
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
|
||||||
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
|
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
|
||||||
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
collectionView.register(ItemCollectionViewCell.self, forCellWithReuseIdentifier: "itemCell")
|
||||||
view.addSubview(collectionView)
|
view.addSubview(collectionView)
|
||||||
|
|
||||||
dataSource = createDataSource()
|
dataSource = createDataSource()
|
||||||
|
@ -50,15 +51,10 @@ class ItemsViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
||||||
let listCell = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { cell, indexPath, item in
|
|
||||||
var config = cell.defaultContentConfiguration()
|
|
||||||
config.text = item.title
|
|
||||||
cell.contentConfiguration = config
|
|
||||||
|
|
||||||
cell.accessories = [.disclosureIndicator()]
|
|
||||||
}
|
|
||||||
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
|
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
|
||||||
return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: item)
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "itemCell", for: indexPath) as! ItemCollectionViewCell
|
||||||
|
cell.updateUI(item: item)
|
||||||
|
return cell
|
||||||
}
|
}
|
||||||
return dataSource
|
return dataSource
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue