96 lines
3.1 KiB
Swift
96 lines
3.1 KiB
Swift
|
//
|
||
|
// SegmentedControlNavigateable.swift
|
||
|
// Mastodon
|
||
|
//
|
||
|
// Created by MainasuK Cirno on 2021-5-21.
|
||
|
//
|
||
|
|
||
|
import UIKit
|
||
|
|
||
|
typealias SegmentedControlNavigateable = SegmentedControlNavigateableCore & SegmentedControlNavigateableRelay
|
||
|
|
||
|
protocol SegmentedControlNavigateableCore: AnyObject {
|
||
|
var navigateableSegmentedControl: UISegmentedControl { get }
|
||
|
var segmentedControlNavigateKeyCommands: [UIKeyCommand] { get }
|
||
|
|
||
|
func segmentedControlNavigateKeyCommandHandler(_ sender: UIKeyCommand)
|
||
|
func navigate(direction: SegmentedControlNavigationDirection)
|
||
|
}
|
||
|
|
||
|
@objc protocol SegmentedControlNavigateableRelay: AnyObject {
|
||
|
func segmentedControlNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand)
|
||
|
}
|
||
|
|
||
|
enum SegmentedControlNavigationDirection: String, CaseIterable {
|
||
|
case previous
|
||
|
case next
|
||
|
|
||
|
var title: String {
|
||
|
switch self {
|
||
|
case .previous: return L10n.Common.Controls.Keyboard.Common.previousSection
|
||
|
case .next: return L10n.Common.Controls.Keyboard.Common.nextSection
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// UIKeyCommand input
|
||
|
var input: String {
|
||
|
switch self {
|
||
|
case .previous: return "["
|
||
|
case .next: return "]"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var modifierFlags: UIKeyModifierFlags {
|
||
|
switch self {
|
||
|
case .previous: return [.shift, .command]
|
||
|
case .next: return [.shift, .command]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var propertyList: Any {
|
||
|
return rawValue
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extension SegmentedControlNavigateableCore where Self: SegmentedControlNavigateableRelay {
|
||
|
var segmentedControlNavigateKeyCommands: [UIKeyCommand] {
|
||
|
SegmentedControlNavigationDirection.allCases.map { direction in
|
||
|
UIKeyCommand(
|
||
|
title: direction.title,
|
||
|
image: nil,
|
||
|
action: #selector(Self.segmentedControlNavigateKeyCommandHandlerRelay(_:)),
|
||
|
input: direction.input,
|
||
|
modifierFlags: direction.modifierFlags,
|
||
|
propertyList: direction.propertyList,
|
||
|
alternates: [],
|
||
|
discoverabilityTitle: nil,
|
||
|
attributes: [],
|
||
|
state: .off
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func segmentedControlNavigateKeyCommandHandler(_ sender: UIKeyCommand) {
|
||
|
guard let rawValue = sender.propertyList as? String,
|
||
|
let direction = SegmentedControlNavigationDirection(rawValue: rawValue) else { return }
|
||
|
navigate(direction: direction)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
extension SegmentedControlNavigateableCore {
|
||
|
func navigate(direction: SegmentedControlNavigationDirection) {
|
||
|
let index: Int = {
|
||
|
let selectedIndex = navigateableSegmentedControl.selectedSegmentIndex
|
||
|
switch direction {
|
||
|
case .previous: return selectedIndex - 1
|
||
|
case .next: return selectedIndex + 1
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
guard 0..<navigateableSegmentedControl.numberOfSegments ~= index else { return }
|
||
|
navigateableSegmentedControl.selectedSegmentIndex = index
|
||
|
navigateableSegmentedControl.sendActions(for: .valueChanged)
|
||
|
}
|
||
|
}
|