private enum ViewType: Int {
case exp
+
case power
+
case power2
+
case power3
}
+/// 2018.02.24
+/// #keyPath(Ship.master_ship.soku)がkeyであるNSSortDescriptorが含まれるとクラッシュする可能性があるため
+/// 新設した#keyPath(Ship.soku)をkeyにするように書き換える
+private func exchangeSortKey(original: [NSSortDescriptor]) -> [NSSortDescriptor] {
+
+ return original
+ .map { sortDesc -> NSSortDescriptor in
+
+ if sortDesc.key == #keyPath(Ship.master_ship.soku) {
+
+ return NSSortDescriptor(key: #keyPath(Ship.soku), ascending: sortDesc.ascending)
+ }
+
+ return sortDesc
+ }
+}
+
final class ShipViewController: MainTabVIewItemViewController {
@objc let managedObjectContext = ServerDataStore.default.context
- deinit {
-
- NotificationCenter.default.removeObserver(self)
- }
+ @IBOutlet private var shipController: NSArrayController!
+ @IBOutlet private var expTableView: NSScrollView!
+ @IBOutlet private var powerTableView: NSScrollView!
+ @IBOutlet private var power2TableView: NSScrollView!
+ @IBOutlet private var power3TableView: NSScrollView!
+ @IBOutlet private weak var standardDeviationField: NSTextField!
+
+ private var sortDescriptorsObservation: NSKeyValueObservation?
+ private var arrangedObjectsObservation: NSKeyValueObservation?
- @IBOutlet var shipController: NSArrayController!
- @IBOutlet var expTableView: NSScrollView!
- @IBOutlet var powerTableView: NSScrollView!
- @IBOutlet var power2TableView: NSScrollView!
- @IBOutlet var power3TableView: NSScrollView!
- @IBOutlet weak var standardDeviationField: NSTextField!
+ private var notificationObserver = NotificationObserver()
override var nibName: NSNib.Name {
override var selectedShipType: ShipTabType {
didSet {
- shipController.filterPredicate = shipTypePredicte
+
+ shipController.filterPredicate = shipTypePredicte(for: selectedShipType)
shipController.rearrangeObjects()
}
}
@objc var standardDeviation: Double {
- guard let ships = shipController.arrangedObjects as? [Ship],
- !ships.isEmpty,
- let avg = shipController.value(forKeyPath: "arrangedObjects.@avg.lv") as? Double
- else { return 0.0 }
+ guard let ships = shipController.arrangedObjects as? [Ship], !ships.isEmpty else {
+
+ return 0.0
+ }
+ guard let avg = shipController.value(forKeyPath: "arrangedObjects.@avg.lv") as? Double else {
+
+ return 0.0
+ }
let total = ships.reduce(0.0) {
return sqrt(total / Double(ships.count))
}
+// @objc dynamic var sortDescriptors: [NSSortDescriptor] {
+// get { return UserDefaults.standard[.shipviewSortDescriptors] }
+// set { UserDefaults.standard[.shipviewSortDescriptors] = sortDescriptors }
+// }
+
private weak var currentTableView: NSView?
override func viewDidLoad() {
}
- shipController.sortDescriptors = UserDefaults.standard[.shipviewSortDescriptors]
- shipController.addObserver(self, forKeyPath: NSBindingName.sortDescriptors.rawValue, context: nil)
- shipController.addObserver(self, forKeyPath: "arrangedObjects", context: nil)
+ shipController.sortDescriptors = exchangeSortKey(original: UserDefaults.standard[.shipviewSortDescriptors])
+
+ sortDescriptorsObservation = shipController.observe(\NSArrayController.sortDescriptors) { [weak self] _, _ in
+
+ UserDefaults.standard[.shipviewSortDescriptors] = self?.shipController.sortDescriptors ?? []
+ }
+ arrangedObjectsObservation = shipController.observe(\NSArrayController.arrangedObjects) { [weak self] _, _ in
+
+ self?.notifyChangeValue(forKey: #keyPath(standardDeviation))
+ }
let tableViews = [expTableView, powerTableView, power2TableView, power3TableView]
tableViews
.forEach {
- NotificationCenter.default
- .addObserver(forName: NSScrollView.didEndLiveScrollNotification, object: $0, queue: nil) {
+ notificationObserver
+ .addObserver(forName: NSScrollView.didEndLiveScrollNotification, object: $0, queue: .main) {
- guard let target = $0.object as? NSScrollView
- else { return }
+ guard let target = $0.object as? NSScrollView else {
+
+ return
+ }
let visibleRect = target.documentVisibleRect
tableViews
#endif
}
- override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
-
- if keyPath == NSBindingName.sortDescriptors.rawValue {
-
- UserDefaults.standard[.shipviewSortDescriptors] = shipController.sortDescriptors
-
- return
- }
-
- if keyPath == "arrangedObjects" {
-
- notifyChangeValue(forKey: "standardDeviation")
-
- return
- }
-
- super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
- }
-
private func showView(with type: ViewType) {
let newSelection: NSView = {
switch type {
+
case .exp: return expTableView
+
case .power: return powerTableView
+
case .power2: return power2TableView
+
case .power3: return power3TableView
+
}
}()
- if currentTableView == newSelection { return }
+ if currentTableView == newSelection {
+
+ return
+ }
- guard let tableView = currentTableView
- else { return }
+ guard let tableView = currentTableView else {
+
+ return
+ }
newSelection.frame = tableView.frame
newSelection.autoresizingMask = tableView.autoresizingMask
return cell?.tag(forSegment: segmented.selectedSegment) ?? -1
case let control as NSControl:
+
return control.tag
default:
+
return -1
+
}
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
- guard let identifier = tableColumn?.identifier
- else { return nil }
+ guard let identifier = tableColumn?.identifier else {
+
+ return nil
+ }
return tableView.makeView(withIdentifier: identifier, owner: nil)
}