Add tick marks to timeline layout sliders

This commit is contained in:
Maurice Parker 2019-11-08 20:11:17 -06:00
parent 0df4498fa3
commit 29b7215f5c
6 changed files with 126 additions and 9 deletions

View File

@ -14,6 +14,7 @@
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
5108F6D42375EEEF001ABC45 /* TimelinePreviewTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */; };
5108F6D623762309001ABC45 /* MasterTimelineIconSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D523762309001ABC45 /* MasterTimelineIconSize.swift */; };
5108F6D823763094001ABC45 /* TickMarkSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D723763094001ABC45 /* TickMarkSlider.swift */; };
51102165233A7D6C0007A5F7 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */; };
5110C37D2373A8D100A9C04F /* InspectorIconHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */; };
51126DA4225FDE2F00722696 /* RSImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */; };
@ -1210,6 +1211,7 @@
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerViewController.swift; sourceTree = "<group>"; };
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
5108F6D523762309001ABC45 /* MasterTimelineIconSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineIconSize.swift; sourceTree = "<group>"; };
5108F6D723763094001ABC45 /* TickMarkSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TickMarkSlider.swift; sourceTree = "<group>"; };
51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = "<group>"; };
5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorIconHeaderView.swift; sourceTree = "<group>"; };
51121AA12265430A00BC0EC1 /* NetNewsWire_iOSapp_target.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSapp_target.xcconfig; sourceTree = "<group>"; };
@ -1864,6 +1866,7 @@
51FFF0C3235EE8E5002762AA /* VibrantButton.swift */,
5186A634235EF3A800C97195 /* VibrantLabel.swift */,
5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */,
5108F6D723763094001ABC45 /* TickMarkSlider.swift */,
);
path = "UIKit Extensions";
sourceTree = "<group>";
@ -3984,6 +3987,7 @@
51EF0F7E2277A57D0050506E /* MasterTimelineAccessibilityCellLayout.swift in Sources */,
51A1699B235E10D700EB091F /* AccountInspectorViewController.swift in Sources */,
51C452762265091600C03939 /* MasterTimelineViewController.swift in Sources */,
5108F6D823763094001ABC45 /* TickMarkSlider.swift in Sources */,
5183CCE9226F68D90010922C /* AccountRefreshTimer.swift in Sources */,
51C452882265093600C03939 /* AddFeedViewController.swift in Sources */,
51A169A0235E10D700EB091F /* FeedbinAccountViewController.swift in Sources */,

View File

@ -161,6 +161,10 @@ struct AppAssets {
return IconImage(UIImage(systemName: "star.fill")!)
}()
static var tickMarkColor: UIColor = {
return UIColor(named: "tickMarkColor")!
}()
static var timelineStarImage: UIImage = {
let image = UIImage(systemName: "star.fill")!
return image.withTintColor(AppAssets.starColor, renderingMode: .alwaysOriginal)

View File

@ -0,0 +1,38 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "228",
"alpha" : "1.000",
"blue" : "230",
"green" : "228"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "59",
"alpha" : "1.000",
"blue" : "63",
"green" : "59"
}
}
}
]
}

View File

@ -660,8 +660,10 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q4t-3M-goU">
<rect key="frame" x="20" y="56" width="374" height="44"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="1" maxValue="3" translatesAutoresizingMaskIntoConstraints="NO" id="AW6-CH-AXP">
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="1" maxValue="3" translatesAutoresizingMaskIntoConstraints="NO" id="AW6-CH-AXP" customClass="TickMarkSlider" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="18" y="7" width="338" height="31"/>
<color key="tintColor" name="secondaryAccentColor"/>
<color key="thumbTintColor" name="primaryAccentColor"/>
<connections>
<action selector="iconSizeChanged:" destination="amD-xZ-U3A" eventType="valueChanged" id="4F9-gj-CJE"/>
</connections>
@ -690,8 +692,10 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oQi-VX-CMV">
<rect key="frame" x="20" y="156" width="374" height="44"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="1" maxValue="6" translatesAutoresizingMaskIntoConstraints="NO" id="AIu-s5-Hvq">
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="1" maxValue="6" translatesAutoresizingMaskIntoConstraints="NO" id="AIu-s5-Hvq" customClass="TickMarkSlider" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="18" y="7" width="338" height="31"/>
<color key="tintColor" name="secondaryAccentColor"/>
<color key="thumbTintColor" name="primaryAccentColor"/>
<connections>
<action selector="numberOfLinesChanged:" destination="amD-xZ-U3A" eventType="valueChanged" id="h25-Da-ZsS"/>
</connections>
@ -794,6 +798,7 @@
<constraint firstAttribute="bottom" secondItem="7do-cs-DNM" secondAttribute="bottom" id="eh9-tn-F3u"/>
<constraint firstItem="7do-cs-DNM" firstAttribute="leading" secondItem="xMG-o1-VfV" secondAttribute="leading" id="kW5-pQ-FCx"/>
</constraints>
<viewLayoutGuide key="safeArea" id="XPF-1A-UKw"/>
</view>
<connections>
<outlet property="tableView" destination="7do-cs-DNM" id="A8q-7w-LCQ"/>
@ -810,5 +815,8 @@
<namedColor name="primaryAccentColor">
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="secondaryAccentColor">
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
</document>

View File

@ -11,9 +11,9 @@ import UIKit
class TimelineCustomizerViewController: UIViewController {
@IBOutlet weak var iconSizeSliderContainerView: UIView!
@IBOutlet weak var iconSizeSlider: UISlider!
@IBOutlet weak var iconSizeSlider: TickMarkSlider!
@IBOutlet weak var numberOfLinesSliderContainerView: UIView!
@IBOutlet weak var numberOfLinesSlider: UISlider!
@IBOutlet weak var numberOfLinesSlider: TickMarkSlider!
@IBOutlet weak var previewWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var previewHeightConstraint: NSLayoutConstraint!
@ -27,10 +27,12 @@ class TimelineCustomizerViewController: UIViewController {
super.viewDidLoad()
iconSizeSliderContainerView.layer.cornerRadius = 12
numberOfLinesSliderContainerView.layer.cornerRadius = 12
numberOfLinesSlider.value = Float(AppDefaults.timelineNumberOfLines)
iconSizeSlider.value = Float(AppDefaults.timelineIconSize.rawValue)
iconSizeSlider.addTickMarks()
numberOfLinesSliderContainerView.layer.cornerRadius = 12
numberOfLinesSlider.value = Float(AppDefaults.timelineNumberOfLines)
numberOfLinesSlider.addTickMarks()
}
override func viewWillAppear(_ animated: Bool) {
@ -45,13 +47,13 @@ class TimelineCustomizerViewController: UIViewController {
}
@IBAction func iconSizeChanged(_ sender: Any) {
guard let iconSize = MasterTimelineIconSize(rawValue: Int(iconSizeSlider.value)) else { return }
guard let iconSize = MasterTimelineIconSize(rawValue: Int(iconSizeSlider.value.rounded())) else { return }
AppDefaults.timelineIconSize = iconSize
updatePreview()
}
@IBAction func numberOfLinesChanged(_ sender: Any) {
AppDefaults.timelineNumberOfLines = Int(numberOfLinesSlider.value)
AppDefaults.timelineNumberOfLines = Int(numberOfLinesSlider.value.rounded())
updatePreview()
}

View File

@ -0,0 +1,61 @@
//
// TickMarkSlider.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 11/8/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import UIKit
class TickMarkSlider: UISlider {
func addTickMarks() {
let numberOfGaps = Int(maximumValue) - Int(minimumValue)
var gapLayoutGuides = [UILayoutGuide]()
for i in 0...numberOfGaps {
let tick = UIView()
tick.translatesAutoresizingMaskIntoConstraints = false
tick.backgroundColor = AppAssets.tickMarkColor
insertSubview(tick, belowSubview: self)
tick.widthAnchor.constraint(equalToConstant: 3).isActive = true
tick.heightAnchor.constraint(equalToConstant: 10).isActive = true
tick.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
if i == 0 {
tick.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
if let lastGapLayoutGuild = gapLayoutGuides.last {
lastGapLayoutGuild.trailingAnchor.constraint(equalTo: tick.leadingAnchor).isActive = true
}
if i != numberOfGaps {
let gapLayoutGuild = UILayoutGuide()
gapLayoutGuides.append(gapLayoutGuild)
addLayoutGuide(gapLayoutGuild)
tick.trailingAnchor.constraint(equalTo: gapLayoutGuild.leadingAnchor).isActive = true
} else {
tick.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
}
if let firstGapLayoutGuild = gapLayoutGuides.first {
for i in 1..<gapLayoutGuides.count {
gapLayoutGuides[i].widthAnchor.constraint(equalTo: firstGapLayoutGuild.widthAnchor).isActive = true
}
}
}
override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
value = value.rounded()
}
}