Information tab completed; cells now dynamically size correctly

This commit is contained in:
Deniz Duezgoeren
2019-07-17 13:05:24 +02:00
parent 347317a5e7
commit 92e3fed7e6
7 changed files with 268 additions and 42 deletions
+45 -1
View File
@@ -55,7 +55,13 @@
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<viewLayoutGuide key="safeArea" id="Or0-Ph-ylC"/>
<items>
<navigationItem title="Personal Plan" id="8j4-CR-EDO"/>
<navigationItem title="Personal Plan" id="8j4-CR-EDO">
<barButtonItem key="rightBarButtonItem" title="Customise" id="iH8-LX-SKF">
<connections>
<action selector="toolbarButtonCustomise:" destination="8rJ-Kc-sve" id="XTh-6F-m3e"/>
</connections>
</barButtonItem>
</navigationItem>
</items>
</navigationBar>
</subviews>
@@ -91,16 +97,54 @@
<navigationItem title="Information" id="9lv-eD-jS6"/>
</items>
</navigationBar>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uw2-gR-W7a">
<rect key="frame" x="0.0" y="88" width="414" height="725"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3fL-cf-hwr">
<rect key="frame" x="0.0" y="0.0" width="414" height="52.333333333333336"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6H8-lj-boN">
<rect key="frame" x="24" y="16" width="366" height="20.333333333333329"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="6H8-lj-boN" firstAttribute="top" secondItem="3fL-cf-hwr" secondAttribute="top" constant="16" id="7vg-94-kgE"/>
<constraint firstAttribute="trailing" secondItem="6H8-lj-boN" secondAttribute="trailing" constant="24" id="L2I-aF-rMP"/>
<constraint firstItem="6H8-lj-boN" firstAttribute="leading" secondItem="3fL-cf-hwr" secondAttribute="leading" constant="24" id="XFt-8f-uB8"/>
<constraint firstAttribute="bottom" secondItem="6H8-lj-boN" secondAttribute="bottom" constant="16" id="ix6-T3-Xby"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="3fL-cf-hwr" firstAttribute="width" secondItem="uw2-gR-W7a" secondAttribute="width" id="2Zp-WB-kqG"/>
<constraint firstItem="3fL-cf-hwr" firstAttribute="top" secondItem="uw2-gR-W7a" secondAttribute="top" id="CK9-Ci-1Uz"/>
<constraint firstItem="3fL-cf-hwr" firstAttribute="leading" secondItem="uw2-gR-W7a" secondAttribute="leading" id="H8E-nR-Ao4"/>
<constraint firstAttribute="trailing" secondItem="3fL-cf-hwr" secondAttribute="trailing" id="Qn2-pu-ejr"/>
<constraint firstAttribute="bottom" secondItem="3fL-cf-hwr" secondAttribute="bottom" id="h0k-Nd-ev6"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="n9O-m5-UQM" firstAttribute="leading" secondItem="eFO-Bf-72I" secondAttribute="leading" id="1Wa-Qr-Bhb"/>
<constraint firstItem="fuI-1W-d0u" firstAttribute="trailing" secondItem="n9O-m5-UQM" secondAttribute="trailing" id="Itb-7h-ird"/>
<constraint firstItem="uw2-gR-W7a" firstAttribute="leading" secondItem="fuI-1W-d0u" secondAttribute="leading" id="SHL-lX-cF5"/>
<constraint firstItem="fuI-1W-d0u" firstAttribute="trailing" secondItem="uw2-gR-W7a" secondAttribute="trailing" id="Ypb-ba-cQV"/>
<constraint firstItem="n9O-m5-UQM" firstAttribute="top" secondItem="fuI-1W-d0u" secondAttribute="top" id="ccZ-hZ-aNP"/>
<constraint firstItem="uw2-gR-W7a" firstAttribute="top" secondItem="n9O-m5-UQM" secondAttribute="bottom" id="dEI-0y-6Nj"/>
<constraint firstItem="fuI-1W-d0u" firstAttribute="bottom" secondItem="uw2-gR-W7a" secondAttribute="bottom" id="uXS-YK-oIz"/>
</constraints>
<viewLayoutGuide key="safeArea" id="fuI-1W-d0u"/>
</view>
<tabBarItem key="tabBarItem" title="Information" image="ic_information" selectedImage="ic_information" id="BQ7-VO-yI4"/>
<connections>
<outlet property="content" destination="6H8-lj-boN" id="Q49-OJ-zsl"/>
<outlet property="scrollView" destination="uw2-gR-W7a" id="C2y-Jf-fgR"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="JwL-CA-SQG" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
+16 -34
View File
@@ -15,6 +15,7 @@ import SQLite
class DataFetcher {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let prefs = UserDefaults.standard
let substitutions = Table("substitutions")
let personal = Table("personal")
@@ -58,11 +59,10 @@ class DataFetcher {
let doc: Document = try SwiftSoup.parse(html)
let rows: Elements = try doc.select("tr")
// let prefs = UserDefaults.standard
// let courses = prefs.string(forKey: "courses")
// let classes = prefs.string(forKey: "classes")
let courses: String? = "GES7"
let classes: String? = "17"
let courses = prefs.string(forKey: "courses")
let classes = prefs.string(forKey: "classes")
// let courses: String? = "GES7"
// let classes: String? = "17"
let db = try Connection("\(path)/db.sqlite3")
@@ -170,32 +170,19 @@ class DataFetcher {
}
func parseInformation(html: String) -> [String] {
var list = [String]()
var info = ""
do {
let doc: Document = try SwiftSoup.parse(html)
let p: Elements = try doc.select("p")
let db = try Connection("\(path)/db.sqlite3")
try db.run(information.create(ifNotExists: true) { t in
t.column(id, primaryKey: true)
t.column(text)
})
try db.run(information.delete())
for item in p {
let t = try item.text()
list.append(t)
let insert = information.insert(text <- t)
_ = try db.run(insert)
if info.isEmpty {
info = try item.text()
} else {
info += "\n\n\(try item.text())"
}
}
_ = prefs.set(info, forKey: "information")
} catch Exception.Error(let type, let message) {
print(type)
@@ -203,18 +190,13 @@ class DataFetcher {
} catch {
print("error")
}
var list = [String]()
list.append(info)
return list
}
func readInformation() -> [String] {
var list = [String]()
do {
let db = try Connection("\(path)/db.sqlite3")
for item in try db.prepare(information) {
list.append(item[text])
}
} catch {}
return list
func readInformation() -> String {
return prefs.string(forKey: "information") ?? ""
}
func parseMenu(html: String) -> [String] {
+30
View File
@@ -10,4 +10,34 @@ import UIKit
class InfoViewController : UIViewController {
@IBOutlet weak var content: UILabel!
let prefs = UserDefaults.standard
@IBOutlet weak var scrollView: UIScrollView!
private let refreshControl = UIRefreshControl()
let df = DataFetcher() // should be a static reference
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if #available(iOS 10.0, *) {
scrollView.refreshControl = refreshControl
} else {
scrollView.addSubview(refreshControl)
}
refreshControl.addTarget(self, action: #selector(objDoAsync(_:)), for: .valueChanged)
refreshControl.tintColor = UIColor(red: 0.39, green: 0.71, blue: 0.96, alpha: 1.0)
refreshControl.attributedTitle = NSAttributedString(string: "Fetching some information...")
self.scrollView.isDirectionalLockEnabled = true
}
@objc private func objDoAsync(_ sender: Any) {
self.df.doAsync(do: "info") { infoArray in
self.content.text = infoArray[0] as? String
self.refreshControl.endRefreshing()
}
}
override func viewDidLoad() {
super.viewDidLoad()
content.text = df.readInformation()
}
}
+69 -2
View File
@@ -14,9 +14,76 @@ class MenuViewCell: MagazineLayoutCollectionViewCell {
@IBOutlet weak var content: UILabel!
override func awakeFromNib() {
private var widthConstraint: NSLayoutConstraint!
public override init(frame: CGRect) {
super.init(frame: frame)
contentView.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
bottomConstraint.priority = .required - 1
NSLayoutConstraint.activate(
[
leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
topAnchor.constraint(equalTo: contentView.topAnchor),
bottomConstraint
]
)
widthConstraint = widthAnchor.constraint(equalToConstant: bounds.width)
widthConstraint.priority = .required - 1
widthConstraint.isActive = true
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override open func awakeFromNib() {
super.awakeFromNib()
// Initialization code
contentView.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
bottomConstraint.priority = .required - 1
NSLayoutConstraint.activate(
[
leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
topAnchor.constraint(equalTo: contentView.topAnchor),
bottomConstraint
]
)
widthConstraint = widthAnchor.constraint(equalToConstant: bounds.width)
widthConstraint.priority = .required - 1
widthConstraint.isActive = true
}
override open func preferredLayoutAttributesFitting(
_ layoutAttributes: UICollectionViewLayoutAttributes)
-> UICollectionViewLayoutAttributes
{
guard let attributes = layoutAttributes as? MagazineLayoutCollectionViewLayoutAttributes else {
assertionFailure("`layoutAttributes` must be an instance of `MagazineLayoutCollectionViewLayoutAttributes`")
return super.preferredLayoutAttributesFitting(layoutAttributes)
}
let size: CGSize
if attributes.shouldVerticallySelfSize {
widthConstraint.constant = layoutAttributes.size.width
size = super.preferredLayoutAttributesFitting(layoutAttributes).size
} else {
// No self-sizing is required; respect whatever size the layout determined.
size = layoutAttributes.size
}
layoutAttributes.size = size
return layoutAttributes
}
}
+38 -2
View File
@@ -11,11 +11,47 @@ import UIKit
class PersonalPlanViewController: PlanViewController {
@IBOutlet weak var toolbar: UINavigationBar!
let prefs = UserDefaults.standard
@IBAction func toolbarButtonCustomise(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: "Customise personal page", message: nil, preferredStyle: .alert)
alert.addTextField { (name) in
name.text = self.prefs.string(forKey: "username")
name.placeholder = "Name"
}
alert.addTextField { (classes) in
classes.text = self.prefs.string(forKey: "classes")
classes.placeholder = "Classes"
}
alert.addTextField { (courses) in
courses.text = self.prefs.string(forKey: "courses")
courses.placeholder = "Courses"
}
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (action) -> Void in
_ = self.prefs.set(alert!.textFields![0].text, forKey: "username")
_ = self.prefs.set(alert!.textFields![1].text, forKey: "classes")
_ = self.prefs.set(alert!.textFields![2].text, forKey: "courses")
_ = self.prefs.synchronize()
}))
self.present(alert, animated: true, completion: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let user = self.prefs.string(forKey: "username")
if (user != nil && user != "") {
if (user!.last == "x" || user!.last == "s" || user!.last == "z") {
self.toolbar!.topItem!.title = "\(user!)' Plan"
} else {
self.toolbar!.topItem!.title = "\(user!)'s Plan"
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func getViewType() -> String {
+69 -2
View File
@@ -19,9 +19,76 @@ class PlanViewCell: MagazineLayoutCollectionViewCell {
@IBOutlet weak var room: UILabel!
@IBOutlet weak var tintView: UIView!
override func awakeFromNib() {
private var widthConstraint: NSLayoutConstraint!
public override init(frame: CGRect) {
super.init(frame: frame)
contentView.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
bottomConstraint.priority = .required - 1
NSLayoutConstraint.activate(
[
leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
topAnchor.constraint(equalTo: contentView.topAnchor),
bottomConstraint
]
)
widthConstraint = widthAnchor.constraint(equalToConstant: bounds.width)
widthConstraint.priority = .required - 1
widthConstraint.isActive = true
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override open func awakeFromNib() {
super.awakeFromNib()
// Initialization code
contentView.translatesAutoresizingMaskIntoConstraints = false
let bottomConstraint = bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
bottomConstraint.priority = .required - 1
NSLayoutConstraint.activate(
[
leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
topAnchor.constraint(equalTo: contentView.topAnchor),
bottomConstraint
]
)
widthConstraint = widthAnchor.constraint(equalToConstant: bounds.width)
widthConstraint.priority = .required - 1
widthConstraint.isActive = true
}
override open func preferredLayoutAttributesFitting(
_ layoutAttributes: UICollectionViewLayoutAttributes)
-> UICollectionViewLayoutAttributes
{
guard let attributes = layoutAttributes as? MagazineLayoutCollectionViewLayoutAttributes else {
assertionFailure("`layoutAttributes` must be an instance of `MagazineLayoutCollectionViewLayoutAttributes`")
return super.preferredLayoutAttributesFitting(layoutAttributes)
}
let size: CGSize
if attributes.shouldVerticallySelfSize {
widthConstraint.constant = layoutAttributes.size.width
size = super.preferredLayoutAttributesFitting(layoutAttributes).size
} else {
// No self-sizing is required; respect whatever size the layout determined.
size = layoutAttributes.size
}
layoutAttributes.size = size
return layoutAttributes
}
}
+1 -1
View File
@@ -65,7 +65,7 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle
}
@objc private func objDoAsync(_ sender: Any) {
df.doAsync(do: getViewType()) { substitutions in
self.df.doAsync(do: self.getViewType()) { substitutions in
self.substs = substitutions as! [SubstModel]
self.collectionView.reloadData()
self.refreshControl.endRefreshing()