Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into kve/element-usage-imp…
Browse files Browse the repository at this point in the history
…rovements

* origin/main: (33 commits)
  Prepare 14.3.0 (#540)
  Custom Update Animations (#539)
  Update version to 14.2.0
  Prepare 14.2.0 release, which contains a Blueprint update
  Bumping versions to 14.1.0 (#535)
  reorder control now proxies accessibility into a seperate element (#533)
  Prepare 14.0.3
  Fix a crash that could occur during cell reuse if a list contained different types of headers. The wrong ObjectIdentifier was being compared and stored.
  Get a repro for the reordering crash reported in #market-ios
  chore: Generated documentation now uses a static copyright notice to avoid noisy diffs (#530)
  Bumping versions to 15.0.2
  fix: Fix tap gesture swallowing touches in swipe actions view
  Bump to 14.0.1
  Fix SPM Blueprint dependency
  Release 14.0.0, update BlueprintUI to 3.0.0 (#525)
  chore: iOS 15 deployment target bump [UI-5187] (#524)
  chore: Bump CI to Xcode 15.1. Bump gems. [UI-5186] (#523)
  fix: don't cancel touches in view for tap gesture recognizer
  fix: don't cancel touches in view for tap gesture recognizer
  Revert weak change
  ...
  • Loading branch information
kyleve committed Aug 6, 2024
2 parents dadf9dd + 5e406ce commit ef78668
Show file tree
Hide file tree
Showing 509 changed files with 18,925 additions and 10,920 deletions.
1 change: 1 addition & 0 deletions .github/workflows/env.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xcode_version=15.1
153 changes: 38 additions & 115 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
@@ -1,152 +1,79 @@
# https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md
# https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
# https://github.com/actions/cache/blob/ff937cc95032836a535d249de4ce2fc52aeae834/examples.md

# https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md
# https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
# https://github.com/actions/cache/blob/ff937cc95032836a535d249de4ce2fc52aeae834/examples.md

name: Tests

on:
pull_request:

jobs:

spm:
name: Swift Package Manager

runs-on: macos-12
runs-on: macos-13-xlarge

steps:
- name: Switch To Xcode 14.2
run: sudo xcode-select -switch /Applications/Xcode_14.2.app
- name: Switch To Xcode 15.1
run: sudo xcode-select -switch /Applications/Xcode_15.1.app

- name: Checkout repository
uses: actions/checkout@v1

# Build

- name: Build
run: swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios15.0-simulator"

ios_16:
name: iOS 16

runs-on: macos-12

steps:
- name: Switch To Xcode 14.2
run: sudo xcode-select -switch /Applications/Xcode_14.2.app

- name: Checkout repository
uses: actions/checkout@v1
run: xcodebuild -scheme "Listable-Package" -destination "platform=iOS Simulator,OS=17.2" -sdk iphonesimulator build

# Build Caching
test:
name: "iOS ${{ matrix.sdk }}"

- name: Cache Bundler
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
runs-on: macos-13-xlarge

- name: Cache Cocoapods
uses: actions/cache@v2
with:
path: Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
strategy:
matrix:
include:
- sdk: "15.4"
simulator_name: iPhone SE (3rd generation)
installation_required: true

# Install & Build
- sdk: "16.2"
simulator_name: iPhone SE (3rd generation)
installation_required: true

- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Pod Install
run: bundle exec pod install --repo-update

- name: Run Tests
run: Scripts/run_ios16_tests.sh

ios_15:
name: iOS 15

runs-on: macos-12
- sdk: "17.2"
simulator_name: iPhone SE (3rd generation)
# The iOS 17.2 SDK is pre-installed on the macOS 13 image.
# Attempting to install it will fail with an error.
installation_required: false

steps:
- name: Switch To Xcode 14
run: sudo xcode-select -switch /Applications/Xcode_14.2.app

- name: Install xcodes
run: brew install aria2 xcodesorg/made/xcodes

- name: Install iOS ${{ matrix.sdk }}
run: sudo xcodes runtimes install "iOS 15.2"

- name: Checkout repository
uses: actions/checkout@v1

# Build Caching
- name: Read env
run: cat .github/workflows/env.properties >> $GITHUB_ENV

- name: Cache Bundler
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Switch to Xcode ${{ env.xcode_version }}
run: sudo xcode-select -s /Applications/Xcode_${{ env.xcode_version }}.app

- name: Cache Cocoapods
uses: actions/cache@v2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
path: Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
# Install & Build

- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Pod Install
run: bundle exec pod install --repo-update

- name: Run Tests
run: Scripts/run_ios15_tests.sh

ios_14:
name: iOS 14

runs-on: macos-12

steps:
- name: Switch To Xcode 14
run: sudo xcode-select -switch /Applications/Xcode_14.2.app
# Uses version specified in .ruby_version
bundler-cache: true # runs 'bundle install' and caches installed gems automatically

- name: Install xcodes
if: ${{ matrix.installation_required }}
run: brew install aria2 xcodesorg/made/xcodes

- name: Install iOS ${{ matrix.sdk }}
run: sudo xcodes runtimes install "iOS 14.5"

- name: Checkout repository
uses: actions/checkout@v1
if: ${{ matrix.installation_required }}
run: sudo xcodes runtimes install "iOS ${{ matrix.sdk }}"

# Build Caching

- name: Cache Bundler
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Cache Cocoapods
uses: actions/cache@v2
with:
Expand All @@ -157,13 +84,9 @@ jobs:
# Install & Build

- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Pod Install
run: bundle exec pod install --repo-update

- name: Run Tests
run: Scripts/run_ios14_tests.sh
- name: Build & Test
run: |
xcodebuild -workspace Demo/Demo.xcworkspace -scheme "Demo" -destination "platform=iOS Simulator,OS=${{ matrix.sdk }},name=${{ matrix.simulator_name }}" build test
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.2
2 changes: 1 addition & 1 deletion BlueprintUILists.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ require_relative 'version'
Pod::Spec.new do |s|
s.name = 'BlueprintUILists'
s.version = LISTABLE_VERSION
s.summary = 'Declarative list views for iOS apps that deploy back to iOS 14.0.'
s.summary = 'Declarative list views for iOS apps that deploy back to iOS 15.0.'
s.homepage = 'https://github.com/kyleve/Listable'
s.license = 'Apache License, Version 2.0'
s.author = { 'Kyle' => '[email protected]' }
Expand Down
96 changes: 78 additions & 18 deletions BlueprintUILists/Sources/ListReorderGesture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Kyle Van Essen on 11/14/19.
//

import Accessibility
import BlueprintUI
import ListableUI
import UIKit
Expand Down Expand Up @@ -38,6 +39,7 @@ import UIKit
/// ```
public struct ListReorderGesture : Element
{

public enum Begins {
case onTap
case onLongPress
Expand All @@ -54,9 +56,8 @@ public struct ListReorderGesture : Element

let actions : ReorderingActions

/// The acccessibility Label of the item that will be reordered.
/// This will be set as the gesture's accessibilityValue to provide a richer VoiceOver utterance.
public var reorderItemAccessibilityLabel : String? = nil
/// The acccessibility label for the reorder element. Defaults to "Reorder".
public var accessibilityLabel : String?

/// Creates a new re-order gesture which wraps the provided element.
///
Expand All @@ -66,6 +67,7 @@ public struct ListReorderGesture : Element
isEnabled : Bool = true,
actions : ReorderingActions,
begins: Begins = .onTap,
accessibilityLabel: String? = nil,
wrapping element : Element
) {
self.isEnabled = isEnabled
Expand All @@ -74,6 +76,8 @@ public struct ListReorderGesture : Element

self.begins = begins

self.accessibilityLabel = accessibilityLabel

self.element = element
}

Expand All @@ -88,24 +92,16 @@ public struct ListReorderGesture : Element
public func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription?
{
return ViewDescription(View.self) { config in

config.builder = {
View(frame: context.bounds, wrapping: self)
}
config.contentView = { $0.containerView }

config.apply { view in
view.isAccessibilityElement = true
view.accessibilityLabel = ListableLocalizedStrings.ReorderGesture.accessibilityLabel
view.accessibilityValue = reorderItemAccessibilityLabel
view.accessibilityHint = ListableLocalizedStrings.ReorderGesture.accessibilityHint
view.accessibilityTraits.formUnion(.button)
view.accessibilityCustomActions = accessibilityActions()

view.recognizer.isEnabled = self.isEnabled

view.recognizer.apply(actions: self.actions)

view.recognizer.minimumPressDuration = begins == .onLongPress ? 0.5 : 0.0
view.apply(self)
}

}
}

Expand All @@ -118,9 +114,14 @@ public extension Element
func listReorderGesture(
with actions : ReorderingActions,
isEnabled : Bool = true,
begins: ListReorderGesture.Begins = .onTap
begins: ListReorderGesture.Begins = .onTap,
accessibilityLabel: String? = nil
) -> Element {
ListReorderGesture(isEnabled: isEnabled, actions: actions, begins: begins, wrapping: self)
ListReorderGesture(isEnabled: isEnabled,
actions: actions,
begins: begins,
accessibilityLabel: accessibilityLabel,
wrapping: self)
}
}

Expand All @@ -129,25 +130,84 @@ fileprivate extension ListReorderGesture
{
private final class View : UIView
{

let containerView = UIView()
let recognizer : ItemReordering.GestureRecognizer
private lazy var proxyElement = UIAccessibilityElement(accessibilityContainer: self)
private var minimumPressDuration: TimeInterval = 0.0 {
didSet {
updateGesturePressDuration()
}
}

@objc private func updateGesturePressDuration() {
self.recognizer.minimumPressDuration = UIAccessibility.isVoiceOverRunning ? 0.0 : self.minimumPressDuration
}

init(frame: CGRect, wrapping : ListReorderGesture)
{
self.recognizer = .init()

super.init(frame: frame)

recognizer.accessibilityProxy = proxyElement
NotificationCenter.default.addObserver(self, selector: #selector(updateGesturePressDuration) , name: UIAccessibility.voiceOverStatusDidChangeNotification, object: nil)

self.isOpaque = false
self.clipsToBounds = false
self.backgroundColor = .clear

self.addGestureRecognizer(self.recognizer)

self.isAccessibilityElement = false

containerView.isOpaque = false
containerView.backgroundColor = .clear
addSubview(containerView)
}

@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
listableInternalFatal()
}

func apply(_ model: ListReorderGesture) {
proxyElement.accessibilityLabel = model.accessibilityLabel ?? ListableLocalizedStrings.ReorderGesture.accessibilityLabel
proxyElement.accessibilityHint = ListableLocalizedStrings.ReorderGesture.accessibilityHint
proxyElement.accessibilityTraits.formUnion(.button)
proxyElement.accessibilityCustomActions = model.accessibilityActions()

recognizer.isEnabled = model.isEnabled

recognizer.apply(actions: model.actions)
minimumPressDuration = model.begins == .onLongPress ? 0.5 : 0.0
}

override func layoutSubviews() {
super.layoutSubviews()
containerView.frame = bounds
}

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if UIAccessibility.isVoiceOverRunning,
UIAccessibility.focusedElement(using: .notificationVoiceOver) as? NSObject == proxyElement {
// Intercept touch events to avoid activating contained elements.
return self
}

return super.hitTest(point, with: event)
}

override var accessibilityElements: [Any]? {
get {
guard recognizer.isEnabled else { return super.accessibilityElements }
proxyElement.accessibilityFrame = self.accessibilityFrame
proxyElement.accessibilityActivationPoint = self.accessibilityActivationPoint
return [containerView, proxyElement]
}
set {
fatalError("Cannot set accessibility elements directly")
}
}
}
}

Expand Down
Loading

0 comments on commit ef78668

Please sign in to comment.