From 92e3fed7e6f0f93e1cd162e7bc11b23e320b9bf9 Mon Sep 17 00:00:00 2001 From: Deniz Duezgoeren Date: Wed, 17 Jul 2019 13:05:24 +0200 Subject: [PATCH] Information tab completed; cells now dynamically size correctly --- AvH Plan/Base.lproj/Main.storyboard | 46 ++++++++++++++- AvH Plan/DataFetcher.swift | 50 +++++----------- AvH Plan/InfoViewController.swift | 30 ++++++++++ AvH Plan/MenuViewCell.swift | 71 ++++++++++++++++++++++- AvH Plan/PersonalPlanViewController.swift | 40 ++++++++++++- AvH Plan/PlanViewCell.swift | 71 ++++++++++++++++++++++- AvH Plan/PlanViewController.swift | 2 +- 7 files changed, 268 insertions(+), 42 deletions(-) diff --git a/AvH Plan/Base.lproj/Main.storyboard b/AvH Plan/Base.lproj/Main.storyboard index aa12b04..6ee8f75 100644 --- a/AvH Plan/Base.lproj/Main.storyboard +++ b/AvH Plan/Base.lproj/Main.storyboard @@ -55,7 +55,13 @@ - + + + + + + + @@ -91,16 +97,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AvH Plan/DataFetcher.swift b/AvH Plan/DataFetcher.swift index 0c80a4f..6641854 100644 --- a/AvH Plan/DataFetcher.swift +++ b/AvH Plan/DataFetcher.swift @@ -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] { diff --git a/AvH Plan/InfoViewController.swift b/AvH Plan/InfoViewController.swift index 926ead7..8b9e65a 100644 --- a/AvH Plan/InfoViewController.swift +++ b/AvH Plan/InfoViewController.swift @@ -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() + } } diff --git a/AvH Plan/MenuViewCell.swift b/AvH Plan/MenuViewCell.swift index 3d1eb46..e1b5742 100644 --- a/AvH Plan/MenuViewCell.swift +++ b/AvH Plan/MenuViewCell.swift @@ -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 } } diff --git a/AvH Plan/PersonalPlanViewController.swift b/AvH Plan/PersonalPlanViewController.swift index da1404a..c81b90d 100644 --- a/AvH Plan/PersonalPlanViewController.swift +++ b/AvH Plan/PersonalPlanViewController.swift @@ -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 { diff --git a/AvH Plan/PlanViewCell.swift b/AvH Plan/PlanViewCell.swift index 34bedd3..40f3541 100644 --- a/AvH Plan/PlanViewCell.swift +++ b/AvH Plan/PlanViewCell.swift @@ -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 } } diff --git a/AvH Plan/PlanViewController.swift b/AvH Plan/PlanViewController.swift index 715fa3f..5428b60 100644 --- a/AvH Plan/PlanViewController.swift +++ b/AvH Plan/PlanViewController.swift @@ -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()