mastodon-ios/Mastodon/Protocol/SegmentedControlNavigateabl...

98 lines
3.2 KiB
Swift

//
// SegmentedControlNavigateable.swift
// Mastodon
//
// Created by MainasuK Cirno on 2021-5-21.
//
import UIKit
import MastodonAsset
import MastodonLocalization
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.SegmentedControl.previousSection
case .next: return L10n.Common.Controls.Keyboard.SegmentedControl.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)
}
}