Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the scroll tracking of WKWebView on iOS 17.4 #630

Merged
merged 2 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Examples/Samples/Samples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
54CDC5D8215BBE23007D205C /* SupplementaryViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54CDC5D7215BBE23007D205C /* SupplementaryViews.swift */; };
54EAD35B263A75EB006A36EA /* PanelLayouts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54EAD35A263A75EB006A36EA /* PanelLayouts.swift */; };
54EAD365263A765F006A36EA /* PagePanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54EAD364263A765F006A36EA /* PagePanelController.swift */; };
54F185822BF4AD0000916F57 /* DebugListCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F185812BF4AD0000916F57 /* DebugListCollectionViewController.swift */; };
54F185842BF4B82E00916F57 /* UnavailableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F185832BF4B82E00916F57 /* UnavailableViewController.swift */; };
5D82A6AD28D1843C006A44BA /* libswiftCoreGraphics.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D82A6AC28D18438006A44BA /* libswiftCoreGraphics.tbd */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -76,6 +78,8 @@
54CDC5D7215BBE23007D205C /* SupplementaryViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupplementaryViews.swift; sourceTree = "<group>"; };
54EAD35A263A75EB006A36EA /* PanelLayouts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelLayouts.swift; sourceTree = "<group>"; };
54EAD364263A765F006A36EA /* PagePanelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagePanelController.swift; sourceTree = "<group>"; };
54F185812BF4AD0000916F57 /* DebugListCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugListCollectionViewController.swift; sourceTree = "<group>"; };
54F185832BF4B82E00916F57 /* UnavailableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnavailableViewController.swift; sourceTree = "<group>"; };
5D82A6AC28D18438006A44BA /* libswiftCoreGraphics.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libswiftCoreGraphics.tbd; path = usr/lib/swift/libswiftCoreGraphics.tbd; sourceTree = SDKROOT; };
/* End PBXFileReference section */

Expand All @@ -97,6 +101,7 @@
children = (
5442E23F25FC533800A26F43 /* DebugTableViewController.swift */,
5442E24925FC53C100A26F43 /* DebugTextViewController.swift */,
54F185812BF4AD0000916F57 /* DebugListCollectionViewController.swift */,
5442E23325FC528400A26F43 /* DetailViewController.swift */,
5442E24325FC538200A26F43 /* InspectorViewController.swift */,
5442E22325FC51AF00A26F43 /* ImageViewController.swift */,
Expand All @@ -106,6 +111,7 @@
5442E22B25FC521F00A26F43 /* SettingsViewController.swift */,
5442E22F25FC525200A26F43 /* TabBarViewController.swift */,
544BC56726CC918200D0A436 /* AdaptiveLayoutTestViewController.swift */,
54F185832BF4B82E00916F57 /* UnavailableViewController.swift */,
);
path = ContentViewControllers;
sourceTree = "<group>";
Expand Down Expand Up @@ -247,6 +253,7 @@
5442E23A25FC52CD00A26F43 /* ModalViewController.swift in Sources */,
5442E22425FC51AF00A26F43 /* ImageViewController.swift in Sources */,
5442E24025FC533800A26F43 /* DebugTableViewController.swift in Sources */,
54F185822BF4AD0000916F57 /* DebugListCollectionViewController.swift in Sources */,
5442E25225FC541700A26F43 /* NestedScrollViewController.swift in Sources */,
5442E22825FC51E200A26F43 /* MultiPanelController.swift in Sources */,
546341A125C6415100CA0596 /* UseCase.swift in Sources */,
Expand All @@ -257,6 +264,7 @@
54EAD365263A765F006A36EA /* PagePanelController.swift in Sources */,
5442E24425FC538200A26F43 /* InspectorViewController.swift in Sources */,
5442E22C25FC521F00A26F43 /* SettingsViewController.swift in Sources */,
54F185842BF4B82E00916F57 /* UnavailableViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2018 the FloatingPanel authors. All rights reserved. MIT license.

import UIKit

@available(iOS 14, *)
class DebugListCollectionViewController: UIViewController {

enum Section {
case main
}

var dataSource: UICollectionViewDiffableDataSource<Section, Int>! = nil
var collectionView: UICollectionView! = nil

override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "List"
configureHierarchy()
configureDataSource()
}
}

@available(iOS 14, *)
extension DebugListCollectionViewController {
/// - Tag: List
private func createLayout() -> UICollectionViewLayout {
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
config.trailingSwipeActionsConfigurationProvider = { indexPath -> UISwipeActionsConfiguration? in
return UISwipeActionsConfiguration(
actions: [UIContextualAction(
style: .destructive,
title: "Delete",
handler: { _, _, completion in
// Do nothing now
}
)]
)
}
return UICollectionViewCompositionalLayout.list(using: config)
}
}

@available(iOS 14, *)
extension DebugListCollectionViewController {
private func configureHierarchy() {
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(collectionView)
collectionView.delegate = self
}
private func configureDataSource() {

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { (cell, indexPath, item) in
var content = cell.defaultContentConfiguration()
content.text = "\(item)"
cell.contentConfiguration = content
}

dataSource = UICollectionViewDiffableDataSource<Section, Int>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, identifier: Int) -> UICollectionViewCell? in

return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: identifier)
}

var snapshot = NSDiffableDataSourceSnapshot<Section, Int>()
snapshot.appendSections([.main])
snapshot.appendItems(Array(0..<94))
dataSource.apply(snapshot, animatingDifferences: false)
}
}

@available(iOS 14, *)
extension DebugListCollectionViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2018 the FloatingPanel authors. All rights reserved. MIT license.

import UIKit

class UnavailableViewController: UIViewController {
weak var label: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel()
label.text = "Unavailable content"
label.numberOfLines = 0
label.textAlignment = .center
label.frame = view.bounds
label.autoresizingMask = [
.flexibleTopMargin,
.flexibleLeftMargin,
.flexibleBottomMargin,
.flexibleRightMargin
]
view.addSubview(label)
self.label = label
}
}
11 changes: 11 additions & 0 deletions Examples/Samples/Sources/UseCases/UseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import UIKit
enum UseCase: Int, CaseIterable {
case trackingTableView
case trackingTextView
case trackingCollectionViewList
case showDetail
case showModal
case showPanelModal
Expand All @@ -31,6 +32,7 @@ extension UseCase {
var name: String {
switch self {
case .trackingTableView: return "Scroll tracking(TableView)"
case .trackingCollectionViewList: return "Scroll tracking(List CollectionView)"
case .trackingTextView: return "Scroll tracking(TextView)"
case .showDetail: return "Show Detail Panel"
case .showModal: return "Show Modal"
Expand Down Expand Up @@ -65,6 +67,15 @@ extension UseCase {
private var content: Content {
switch self {
case .trackingTableView: return .viewController(DebugTableViewController())
case .trackingCollectionViewList:
if #available(iOS 14, *) {
return .viewController(DebugListCollectionViewController())
} else {
let vc = UnavailableViewController()
vc.loadViewIfNeeded()
vc.label.text = "UICollectionLayoutListConfiguration is unavailable.\nBuild this app on iOS 14 and later."
return .viewController(vc)
}
case .trackingTextView: return .storyboard("ConsoleViewController") // Storyboard only
case .showDetail: return .storyboard(String(describing: DetailViewController.self))
case .showModal: return .storyboard(String(describing: ModalViewController.self))
Expand Down
24 changes: 24 additions & 0 deletions Examples/Samples/Sources/UseCases/UseCaseController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ extension UseCaseController {
fpc.ext_trackScrollView(in: contentVC)
addMain(panel: fpc)

case .trackingCollectionViewList:
let fpc = FloatingPanelController()
fpc.delegate = self
fpc.contentInsetAdjustmentBehavior = .always
fpc.surfaceView.appearance = {
let appearance = SurfaceAppearance()
appearance.cornerRadius = 6.0
return appearance
}()

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(UseCaseController.handleSurface(tapGesture:)))
tapGesture.cancelsTouchesInView = false
tapGesture.numberOfTapsRequired = 2
// Prevents a delay to response a tap in menus of DebugTableViewController.
tapGesture.delaysTouchesEnded = false
fpc.surfaceView.addGestureRecognizer(tapGesture)

fpc.set(contentViewController: contentVC)
if #available(iOS 14, *),
let scrollView = (fpc.contentViewController as? DebugListCollectionViewController)?.collectionView {
fpc.track(scrollView: scrollView)
}
addMain(panel: fpc)

case .trackingTextView:
let fpc = FloatingPanelController()
fpc.delegate = self
Expand Down
13 changes: 9 additions & 4 deletions Sources/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -588,11 +588,16 @@ class Core: NSObject, UIGestureRecognizerDelegate {
// When no scrollView, nothing to handle.
guard let scrollView = scrollView, scrollView.frame.contains(initialLocation) else { return false }

// For _UISwipeActionPanGestureRecognizer
if let scrollGestureRecognizers = scrollView.gestureRecognizers {
// Prevents moving a panel on swipe actions using _UISwipeActionPanGestureRecognizer.
// [Warning] Do not apply this to WKWebView. Since iOS 17.4, WKWebView has an additional pan
// gesture recognizer besides UIScrollViewPanGestureRecognizer. Applying this to WKWebView
// will block panel movements because another pan gesture isn't `scrollView.panGestureRecognizer`.
if let scrollGestureRecognizers = scrollView.gestureRecognizers,
scrollView is UITableView || scrollView is UICollectionView {
for gesture in scrollGestureRecognizers {
guard gesture.state == .began || gesture.state == .changed
else { continue }
guard gesture.state == .began || gesture.state == .changed else {
continue
}

if gesture != scrollView.panGestureRecognizer {
return true
Expand Down
Loading