M Ferry widget/TodayViewController.swift => Ferry widget/TodayViewController.swift +3 -4
@@ 17,7 17,7 @@ class TodayViewController: UIViewController, NCWidgetProviding, CLLocationManage
}()
lazy var residentScheduleView = {
- ResidenceSchedulesView(frame: .zero)
+ WidgetResidenceSchedulesView(frame: .zero)
}()
var location: CLLocation? = nil {
didSet {
@@ 48,8 48,7 @@ class TodayViewController: UIViewController, NCWidgetProviding, CLLocationManage
}
func reload() {
- let island = UserDefaults(suiteName: "group.net.b123400.ferriestimetable")?.string(forKey: "widget-island")
- .flatMap { Island.init(rawValue:$0) } ?? Island.centralCheungChau
+ let island = ModelManager.shared.homeRoute ?? .centralCheungChau
let schedule = Schedule(raws: ModelManager.shared.getRaws())
if ModelManager.shared.residentModeReady, let l = location, let direction = ModelManager.shared.residenceDirectionWith(location: l) {
@@ 59,7 58,7 @@ class TodayViewController: UIViewController, NCWidgetProviding, CLLocationManage
self.scheduleView.removeFromSuperview()
}
let ferries = schedule.upcomingFerries(island: island, direction: direction, count: 4)
- residentScheduleView.apply(model: ResidenceSchedulesView.Model(
+ residentScheduleView.apply(model: WidgetResidenceSchedulesView.Model(
island: island,
direction: direction,
ferries: ferries
A Ferry widget/WidgetResidenceSchedulesView.swift => Ferry widget/WidgetResidenceSchedulesView.swift +130 -0
@@ 0,0 1,130 @@
+//
+// ResidentSchedulesView.swift
+// Ferry widget
+//
+// Created by b123400 on 2021/06/06.
+// Copyright © 2021 b123400. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+private var titleFont: UIFont = UIFontMetrics(forTextStyle: .largeTitle)
+ .scaledFont(for: UIFont.monospacedDigitSystemFont(ofSize: 26, weight: .regular))
+
+private var subheadFont: UIFont = UIFontMetrics(forTextStyle: .subheadline)
+ .scaledFont(for: UIFont.monospacedDigitSystemFont(ofSize: 17, weight: .regular))
+
+class WidgetResidenceScheduleView: UIView {
+ lazy var label: UILabel = {
+ let l = UILabel()
+ l.font = titleFont
+ return l
+ }()
+ lazy var subLabel: UILabel = {
+ let l = UILabel()
+ l.font = subheadFont
+ l.textColor = UIColor.secondaryLabel
+ return l
+ }()
+ lazy var colorView: UIView = {
+ let v = UIView()
+ v.layer.cornerRadius = 2.5
+ return v
+ }()
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ self.addSubview(self.label)
+ self.addSubview(self.subLabel)
+ self.addSubview(self.colorView)
+
+ label.snp.makeConstraints { (make) in
+ make.top.left.bottom.equalToSuperview()
+ }
+ subLabel.snp.makeConstraints { (make) in
+ make.left.equalTo(label.snp.right).offset(50)
+ make.centerY.equalTo(label.snp.centerY)
+ }
+ colorView.snp.makeConstraints { (make) in
+ make.top.bottom.equalTo(label)
+ make.width.equalTo(5)
+ make.left.equalTo(label.snp.right).offset(8)
+ }
+ }
+}
+
+class WidgetResidenceSchedulesView: UIView {
+
+ public struct Model {
+ let island: Island
+ let direction: Direction
+ let ferries: [Ferry<Date>]
+ }
+
+ lazy var label: UILabel = {
+ let l = UILabel()
+ l.font = titleFont
+ l.adjustsFontSizeToFitWidth = true
+ l.minimumScaleFactor = 0.5
+ return l
+ }()
+
+ lazy var count: Int = 4 {
+ didSet {
+ rows = [0..<count].map { _ in
+ WidgetResidenceScheduleView()
+ }
+ }
+ }
+
+ var rows = [
+ WidgetResidenceScheduleView(),
+ WidgetResidenceScheduleView(),
+ WidgetResidenceScheduleView(),
+ WidgetResidenceScheduleView()
+ ]
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ self.addSubview(label)
+ label.snp.makeConstraints { make in
+ make.top.right.equalToSuperview()
+ make.left.equalToSuperview().offset(8)
+ }
+
+ let stack = UIStackView(arrangedSubviews: self.rows)
+ stack.axis = .vertical
+ stack.spacing = 8
+ self.addSubview(stack)
+
+ stack.snp.makeConstraints { make in
+ make.top.equalTo(label.snp.bottom).offset(8)
+ make.left.equalToSuperview().offset(8)
+ make.right.equalToSuperview()
+ }
+ }
+
+ func apply(model: Model) {
+ label.text = model.island.nameForDirection(direction: model.direction)
+ for i in 0..<rows.count {
+ if i < model.ferries.count {
+ let row = rows[i]
+ let ferry = model.ferries[i]
+ row.label.text = ferry.time.timeString
+ row.subLabel.text = timeLeft(date: ferry.time)
+ row.colorView.backgroundColor = ferry.color
+ }
+ }
+ }
+}
M FerryTimeTable3.xcodeproj/project.pbxproj => FerryTimeTable3.xcodeproj/project.pbxproj +4 -2
@@ 15,6 15,7 @@
CF0FF14724CAEE5300CB9676 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CF0FF14524CAEE5300CB9676 /* MainInterface.storyboard */; };
CF0FF14B24CAEE5300CB9676 /* Ferry Timetable.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CF0FF13E24CAEE5300CB9676 /* Ferry Timetable.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
CF1E4A4324ACDC9300D98F41 /* LeftAlignedCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF1E4A4224ACDC9300D98F41 /* LeftAlignedCollectionViewFlowLayout.swift */; };
+ CF271D3D266D197D00A853C8 /* WidgetResidenceSchedulesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF271D3C266D197D00A853C8 /* WidgetResidenceSchedulesView.swift */; };
CF547F8324C339F9007DCF39 /* raws.json in Resources */ = {isa = PBXBuildFile; fileRef = CF547F8224C339F9007DCF39 /* raws.json */; };
CF547F8524C33C46007DCF39 /* Schedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF547F8424C33C46007DCF39 /* Schedule.swift */; };
CF547F8824C359A0007DCF39 /* MenuCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF547F8724C359A0007DCF39 /* MenuCell.swift */; };
@@ 71,7 72,6 @@
CFDAF408265A6312000E973A /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFDAF406265A6308000E973A /* CoreLocation.framework */; };
CFE1044C24CAB69B00AB1B80 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE1044B24CAB69B00AB1B80 /* SettingsView.swift */; };
CFEF2C1424CADCCE00DA70A4 /* Json.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFEF2C1324CADCCE00DA70A4 /* Json.swift */; };
- CFF0A8D0266B9304002AC7FE /* ResidenceSchedulesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF9A58AF2663BA67003FDFFA /* ResidenceSchedulesView.swift */; };
FD342830DA4812F7F903F66C /* Pods_FerryTimetable3.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F085409AD139E84060EF67C8 /* Pods_FerryTimetable3.framework */; };
/* End PBXBuildFile section */
@@ 130,6 130,7 @@
CF0FF14624CAEE5300CB9676 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
CF0FF14824CAEE5300CB9676 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CF1E4A4224ACDC9300D98F41 /* LeftAlignedCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftAlignedCollectionViewFlowLayout.swift; sourceTree = "<group>"; };
+ CF271D3C266D197D00A853C8 /* WidgetResidenceSchedulesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetResidenceSchedulesView.swift; sourceTree = "<group>"; };
CF547F8224C339F9007DCF39 /* raws.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = raws.json; sourceTree = "<group>"; };
CF547F8424C33C46007DCF39 /* Schedule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Schedule.swift; sourceTree = "<group>"; };
CF547F8724C359A0007DCF39 /* MenuCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCell.swift; sourceTree = "<group>"; };
@@ 273,6 274,7 @@
CFC73E6424D8369B00CA4F41 /* InfoPlist.strings */,
CFC73E5E24D8336E00CA4F41 /* Localizable.strings */,
CF5A5ADE24CB033000DDF6BB /* WidgetView.swift */,
+ CF271D3C266D197D00A853C8 /* WidgetResidenceSchedulesView.swift */,
);
path = "Ferry widget";
sourceTree = "<group>";
@@ 722,7 724,7 @@
CF5A5AD424CAFA2500DDF6BB /* MenuCell.swift in Sources */,
CF5A5AD724CAFA8900DDF6BB /* Timetable.swift in Sources */,
CF5A5AE424CB757300DDF6BB /* CurrentScheduleView.swift in Sources */,
- CFF0A8D0266B9304002AC7FE /* ResidenceSchedulesView.swift in Sources */,
+ CF271D3D266D197D00A853C8 /* WidgetResidenceSchedulesView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};