Archived
Information tab completed; cells now dynamically size correctly
This commit is contained in:
@@ -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
@@ -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] {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user