Skip to content

Commit

Permalink
Bk/another accessibility refactor (#297)
Browse files Browse the repository at this point in the history
* Update ItemViewReuseManager and tests

* Simplify accessibility implementation in CalendarView

PR feedback

* Update Github actions
  • Loading branch information
bryankeller authored Jan 29, 2024
1 parent ef63533 commit 6d6d11a
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 114 deletions.
21 changes: 12 additions & 9 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Swift
name: CI

on:
push:
Expand All @@ -8,22 +8,25 @@ on:

jobs:
build:
runs-on: macos-latest
runs-on: macos-13
strategy:
matrix:
destination: ['platform=iOS Simulator,OS=11.0,name=iPhone 8', 'platform=iOS Simulator,OS=16.2,name=iPhone 14']
xcode:
- '15.0' # Swift 5.9
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Build
run: xcodebuild clean build -scheme HorizonCalendar
run: xcodebuild clean build -scheme HorizonCalendar -destination "generic/platform=iOS Simulator"
- name: Run tests
run: xcodebuild clean test -project HorizonCalendar.xcodeproj -scheme HorizonCalendar -destination "name=iPhone 8,OS=16.2"
run: xcodebuild clean test -project HorizonCalendar.xcodeproj -scheme HorizonCalendar -destination "name=iPhone 14,OS=17.2"

lint-swift:
runs-on: macos-13
strategy:
matrix:
xcode:
- '15.0' # Swift 5.9
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Lint Swift
run: swift package --allow-writing-to-package-directory format --lint


6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support for disabling touch handling on SwiftUI views via the `allowsHitTesting` modifier

### Fixed
- Fixed an issue that could cause accessibility focus to shift unexpectedly

### Changed
- Rewrote accessibility code to avoid posting notifications, which causes poor Voice Over performance and odd focus bugs

## [v2.0.0](https://github.com/airbnb/HorizonCalendar/compare/v1.16.0...v2.0.0) - 2023-12-19

### Added
Expand Down
4 changes: 2 additions & 2 deletions HorizonCalendar.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Features:
spec.homepage = "https://github.com/airbnb/HorizonCalendar"
spec.authors = { "Bryan Keller" => "[email protected]" }
spec.social_media_url = "https://twitter.com/BKYourWay19"
spec.swift_version = "5.8"
spec.ios.deployment_target = '11.0'
spec.swift_version = "5.9"
spec.ios.deployment_target = '12.0'
spec.source_files = "Sources/**/*.{swift,h}"
end
10 changes: 6 additions & 4 deletions HorizonCalendar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
Expand Down Expand Up @@ -622,6 +623,7 @@
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
Expand All @@ -644,7 +646,7 @@
GCC_WARN_UNUSED_PARAMETER = YES;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -678,7 +680,7 @@
GCC_WARN_UNUSED_PARAMETER = YES;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -702,7 +704,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 5Q5SGQT2R4;
INFOPLIST_FILE = Tests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -722,7 +724,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 5Q5SGQT2R4;
INFOPLIST_FILE = Tests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
5 changes: 2 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// swift-tools-version:5.8

// swift-tools-version: 5.8.1
import PackageDescription

let package = Package(
name: "HorizonCalendar",
platforms: [
.iOS(.v11),
.iOS(.v12),
],
products: [
.library(name: "HorizonCalendar", targets: ["HorizonCalendar"]),
Expand Down
8 changes: 6 additions & 2 deletions Sources/Internal/ItemViewReuseManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ final class ItemViewReuseManager {

func viewsForVisibleItems(
_ visibleItems: Set<VisibleItem>,
recycleUnusedViews: Bool,
viewHandler: (
ItemView,
VisibleItem,
Expand Down Expand Up @@ -56,6 +57,7 @@ final class ItemViewReuseManager {

let context = reusedViewContext(
for: visibleItem,
recycleUnusedViews: recycleUnusedViews,
unusedPreviouslyVisibleItems: &visibleItemsDifference)
viewHandler(
context.view,
Expand All @@ -76,6 +78,7 @@ final class ItemViewReuseManager {

private func reusedViewContext(
for visibleItem: VisibleItem,
recycleUnusedViews: Bool,
unusedPreviouslyVisibleItems: inout Set<VisibleItem>)
-> ReusedViewContext
{
Expand Down Expand Up @@ -103,7 +106,7 @@ final class ItemViewReuseManager {
visibleItemsForItemViewDifferentiators[differentiator]?.remove(visibleItem)
viewsForVisibleItems.removeValue(forKey: visibleItem)
} else {
if let previouslyVisibleItem = unusedPreviouslyVisibleItems.first {
if recycleUnusedViews, let previouslyVisibleItem = unusedPreviouslyVisibleItems.first {
// An unused, previously-visible item is available, so reuse it.

guard let previousView = viewsForVisibleItems[previouslyVisibleItem] else {
Expand All @@ -122,7 +125,8 @@ final class ItemViewReuseManager {
visibleItemsForItemViewDifferentiators[differentiator]?.remove(previouslyVisibleItem)
viewsForVisibleItems.removeValue(forKey: previouslyVisibleItem)
} else {
// No previously-visible item is available for reuse, so create a new view.
// No previously-visible item is available for reuse (or view recycling is disabled), so
// create a new view.
view = ItemView(initialCalendarItemModel: visibleItem.calendarItemModel)
previousBackingVisibleItem = nil
isReusedViewSameAsPreviousView = false
Expand Down
124 changes: 72 additions & 52 deletions Sources/Internal/SubviewInsertionIndexTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,79 +27,33 @@ final class SubviewInsertionIndexTracker {
switch itemType {
case .monthBackground:
index = monthBackgroundItemsEndIndex
monthBackgroundItemsEndIndex += 1
dayRangeItemsEndIndex += 1
mainItemsEndIndex += 1
daysOfWeekRowSeparatorItemsEndIndex += 1
overlayItemsEndIndex += 1
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .dayBackground:
index = dayBackgroundItemsEndIndex
dayBackgroundItemsEndIndex += 1
dayRangeItemsEndIndex += 1
mainItemsEndIndex += 1
daysOfWeekRowSeparatorItemsEndIndex += 1
overlayItemsEndIndex += 1
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .dayRange:
index = dayRangeItemsEndIndex
dayRangeItemsEndIndex += 1
mainItemsEndIndex += 1
daysOfWeekRowSeparatorItemsEndIndex += 1
overlayItemsEndIndex += 1
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .layoutItemType:
index = mainItemsEndIndex
mainItemsEndIndex += 1
daysOfWeekRowSeparatorItemsEndIndex += 1
overlayItemsEndIndex += 1
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .daysOfWeekRowSeparator:
index = daysOfWeekRowSeparatorItemsEndIndex
daysOfWeekRowSeparatorItemsEndIndex += 1
overlayItemsEndIndex += 1
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .overlayItem:
index = overlayItemsEndIndex
overlayItemsEndIndex += 1
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .pinnedDaysOfWeekRowBackground:
index = pinnedDaysOfWeekRowBackgroundEndIndex
pinnedDaysOfWeekRowBackgroundEndIndex += 1
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .pinnedDayOfWeek:
index = pinnedDayOfWeekItemsEndIndex
pinnedDayOfWeekItemsEndIndex += 1
pinnedDaysOfWeekRowSeparatorEndIndex += 1

case .pinnedDaysOfWeekRowSeparator:
index = pinnedDaysOfWeekRowSeparatorEndIndex
pinnedDaysOfWeekRowSeparatorEndIndex += 1
}

addValue(1, toItemTypesAffectedBy: itemType)

return index
}

func removedSubview(withCorrespondingItemType itemType: VisibleItem.ItemType) {
addValue(-1, toItemTypesAffectedBy: itemType)
}

// MARK: Private

private var monthBackgroundItemsEndIndex = 0
Expand All @@ -112,4 +66,70 @@ final class SubviewInsertionIndexTracker {
private var pinnedDayOfWeekItemsEndIndex = 0
private var pinnedDaysOfWeekRowSeparatorEndIndex = 0

private func addValue(_ value: Int, toItemTypesAffectedBy itemType: VisibleItem.ItemType) {
switch itemType {
case .monthBackground:
monthBackgroundItemsEndIndex += value
dayRangeItemsEndIndex += value
mainItemsEndIndex += value
daysOfWeekRowSeparatorItemsEndIndex += value
overlayItemsEndIndex += value
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .dayBackground:
dayBackgroundItemsEndIndex += value
dayRangeItemsEndIndex += value
mainItemsEndIndex += value
daysOfWeekRowSeparatorItemsEndIndex += value
overlayItemsEndIndex += value
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .dayRange:
dayRangeItemsEndIndex += value
mainItemsEndIndex += value
daysOfWeekRowSeparatorItemsEndIndex += value
overlayItemsEndIndex += value
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .layoutItemType:
mainItemsEndIndex += value
daysOfWeekRowSeparatorItemsEndIndex += value
overlayItemsEndIndex += value
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .daysOfWeekRowSeparator:
daysOfWeekRowSeparatorItemsEndIndex += value
overlayItemsEndIndex += value
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .overlayItem:
overlayItemsEndIndex += value
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .pinnedDaysOfWeekRowBackground:
pinnedDaysOfWeekRowBackgroundEndIndex += value
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .pinnedDayOfWeek:
pinnedDayOfWeekItemsEndIndex += value
pinnedDaysOfWeekRowSeparatorEndIndex += value

case .pinnedDaysOfWeekRowSeparator:
pinnedDaysOfWeekRowSeparatorEndIndex += value
}
}

}
Loading

0 comments on commit 6d6d11a

Please sign in to comment.