Skip to content

Commit

Permalink
Fix ContextMenu on iOS 17
Browse files Browse the repository at this point in the history
  • Loading branch information
Lakr233 committed Sep 16, 2023
1 parent 6f0c984 commit 6a80491
Show file tree
Hide file tree
Showing 89 changed files with 826 additions and 92 deletions.
32 changes: 28 additions & 4 deletions Kimis.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
503809AD2977B7B3004C9438 /* FollowingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503809AC2977B7B3004C9438 /* FollowingController.swift */; };
503809AF2977BA46004C9438 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503809AE2977BA46004C9438 /* ViewController.swift */; };
503809B12977D27E004C9438 /* CGPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503809B02977D27E004C9438 /* CGPoint.swift */; };
503A833C2AB40DE500D240D3 /* ChidoriMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503A83382AB40DE500D240D3 /* ChidoriMenu.swift */; };
503A833D2AB40DE500D240D3 /* ChidoriMenuTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503A83392AB40DE500D240D3 /* ChidoriMenuTableViewCell.swift */; };
503A833E2AB40DE500D240D3 /* ChidoriAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503A833A2AB40DE500D240D3 /* ChidoriAnimationController.swift */; };
503A833F2AB40DE500D240D3 /* ChidoriPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503A833B2AB40DE500D240D3 /* ChidoriPresentationController.swift */; };
50443F862927B9190077523F /* Source in Frameworks */ = {isa = PBXBuildFile; productRef = 50443F852927B9190077523F /* Source */; };
50443F8A2927D4E10077523F /* NoteCell+Context.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50443F892927D4E10077523F /* NoteCell+Context.swift */; };
50443F8F2927D5050077523F /* NotePreviewSimple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50443F8E2927D5050077523F /* NotePreviewSimple.swift */; };
Expand Down Expand Up @@ -305,6 +309,10 @@
503809AC2977B7B3004C9438 /* FollowingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingController.swift; sourceTree = "<group>"; };
503809AE2977BA46004C9438 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
503809B02977D27E004C9438 /* CGPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGPoint.swift; sourceTree = "<group>"; };
503A83382AB40DE500D240D3 /* ChidoriMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChidoriMenu.swift; sourceTree = "<group>"; };
503A83392AB40DE500D240D3 /* ChidoriMenuTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChidoriMenuTableViewCell.swift; sourceTree = "<group>"; };
503A833A2AB40DE500D240D3 /* ChidoriAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChidoriAnimationController.swift; sourceTree = "<group>"; };
503A833B2AB40DE500D240D3 /* ChidoriPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChidoriPresentationController.swift; sourceTree = "<group>"; };
50443F892927D4E10077523F /* NoteCell+Context.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NoteCell+Context.swift"; sourceTree = "<group>"; };
50443F8E2927D5050077523F /* NotePreviewSimple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotePreviewSimple.swift; sourceTree = "<group>"; };
50443F902927D78A0077523F /* NotePreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotePreview.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -639,6 +647,17 @@
path = FollowingController;
sourceTree = "<group>";
};
503A83372AB40DDB00D240D3 /* Menu */ = {
isa = PBXGroup;
children = (
503A83382AB40DE500D240D3 /* ChidoriMenu.swift */,
503A83392AB40DE500D240D3 /* ChidoriMenuTableViewCell.swift */,
503A833B2AB40DE500D240D3 /* ChidoriPresentationController.swift */,
503A833A2AB40DE500D240D3 /* ChidoriAnimationController.swift */,
);
path = Menu;
sourceTree = "<group>";
};
50443F8B2927D4E60077523F /* Abstract */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1042,6 +1061,7 @@
50BED14829277D0D00C9D7E2 /* Extension */ = {
isa = PBXGroup;
children = (
503A83372AB40DDB00D240D3 /* Menu */,
50BED15E29277D0E00C9D7E2 /* Generic */,
508FE990292B43E8005D1933 /* Module */,
50BED14929277D0D00C9D7E2 /* Property */,
Expand Down Expand Up @@ -1665,13 +1685,15 @@
503809AB2977B7AC004C9438 /* FollowerController.swift in Sources */,
50BED1C029277D0E00C9D7E2 /* UIImage+Fluent.swift in Sources */,
50BED1DB29277D0E00C9D7E2 /* NoteCell+Full.swift in Sources */,
503A833F2AB40DE500D240D3 /* ChidoriPresentationController.swift in Sources */,
50126257292F78D6002E1636 /* Collection.swift in Sources */,
5045198F296C21F7009D613D /* AttachmentDrivePicker+Cell.swift in Sources */,
50BED1D829277D0E00C9D7E2 /* NoteCell+MoreHeader.swift in Sources */,
502015F5296FFB1600C57E39 /* AttachmentDrivePicker+Delegate.swift in Sources */,
504519A5296D55EC009D613D /* Toolbar+Picture.swift in Sources */,
504519A7296D55EC009D613D /* Toolbar+Poll.swift in Sources */,
50BED1FA29277D0E00C9D7E2 /* SceneDelegate.swift in Sources */,
503A833D2AB40DE500D240D3 /* ChidoriMenuTableViewCell.swift in Sources */,
50BED1BD29277D0E00C9D7E2 /* UIImage+BlurHash.swift in Sources */,
504E87D629377B4E00BDE03C /* NotificationCell+Kind.swift in Sources */,
50E8DFD8297B433100657910 /* LicenseController.swift in Sources */,
Expand Down Expand Up @@ -1765,9 +1787,11 @@
505826242935004700E72238 /* UserViewController+Scroll.swift in Sources */,
50FF63EC2969A46700DBB4CA /* UIButton.swift in Sources */,
50443F8A2927D4E10077523F /* NoteCell+Context.swift in Sources */,
503A833C2AB40DE500D240D3 /* ChidoriMenu.swift in Sources */,
50BED1BF29277D0E00C9D7E2 /* AlignedCollectionViewFlowLayout.swift in Sources */,
5069EBB2295EDD3100677A3F /* SmallUsersListController.swift in Sources */,
50BED1C229277D0E00C9D7E2 /* TextView.swift in Sources */,
503A833E2AB40DE500D240D3 /* ChidoriAnimationController.swift in Sources */,
5065E4E429352B22001C540C /* TextParser+Email.swift in Sources */,
50BED20329277D0E00C9D7E2 /* TextParser+Body.swift in Sources */,
50CEBEBC2A6A455900484FD8 /* UserSimpleBannerView.swift in Sources */,
Expand Down Expand Up @@ -1924,7 +1948,7 @@
CODE_SIGN_ENTITLEMENTS = Kimis/KimisDebug.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 152;
CURRENT_PROJECT_VERSION = 164;
DEVELOPMENT_TEAM = 6CMYQQFFT8;
"ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand All @@ -1942,7 +1966,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.15;
MARKETING_VERSION = 1.16;
PRODUCT_BUNDLE_IDENTIFIER = wiki.qaq.kimis.inhouse;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand All @@ -1963,7 +1987,7 @@
CODE_SIGN_ENTITLEMENTS = Kimis/Kimis.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 152;
CURRENT_PROJECT_VERSION = 164;
DEVELOPMENT_TEAM = 6CMYQQFFT8;
"ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand All @@ -1981,7 +2005,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.15;
MARKETING_VERSION = 1.16;
PRODUCT_BUNDLE_IDENTIFIER = as.wiki.qaq.kimis;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
2 changes: 1 addition & 1 deletion Kimis/App/AppConfig.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Configuration.swift
// AppConfig.swift
// mTale
//
// Created by Lakr Aream on 2022/3/31.
Expand Down
2 changes: 1 addition & 1 deletion Kimis/App/AppTask.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// AppDelegate.swift
// AppTask.swift
// Kimis
//
// Created by Lakr Aream on 2022/11/14.
Expand Down
2 changes: 1 addition & 1 deletion Kimis/Backend/TextParser/Helper/Enumerator.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// TextParser+RegEx.swift
// Enumerator.swift
// Kimis
//
// Created by Lakr Aream on 2022/11/10.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// TextParser+Adv.swift
// TextParser+DollarAttribute.swift
// Kimis
//
// Created by Lakr Aream on 2022/12/5.
Expand Down
2 changes: 1 addition & 1 deletion Kimis/Backend/TextParser/Render/TextParser+Body.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// TextParser+Text.swift
// TextParser+Body.swift
// Kimis
//
// Created by Lakr Aream on 2022/5/3.
Expand Down
2 changes: 1 addition & 1 deletion Kimis/Backend/TextParser/Render/TextParser+Footer.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// TextParser+Text.swift
// TextParser+Footer.swift
// Kimis
//
// Created by Lakr Aream on 2022/5/3.
Expand Down
126 changes: 126 additions & 0 deletions Kimis/Extension/Menu/ChidoriAnimationController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//
// ChidoriAnimationController.swift
// Chidori
//
// Created by Christian Selig on 2021-02-15.
//

import UIKit

class ChidoriAnimationController: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerInteractiveTransitioning {
enum AnimationControllerType { case presentation, dismissal }

let type: AnimationControllerType

var animatorForCurrentSession: UIViewPropertyAnimator?

weak var context: UIViewControllerContextTransitioning?

init(type: AnimationControllerType) {
self.type = type
}

func transitionDuration(using _: UIViewControllerContextTransitioning?) -> TimeInterval {
0.4
}

func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) {
context = transitionContext
animateTransition(using: transitionContext)
}

func cancelTransition() {
guard let context,
let animator = animatorForCurrentSession else { return }

// Cancel the current transition
context.cancelInteractiveTransition()

// Play the animation in reverse
animator.isReversed = true
animator.startAnimation()

if type == .presentation {
if let presentingViewController = context.viewController(forKey: .from) {
presentingViewController.view.tintAdjustmentMode = .automatic
} else {
preconditionFailure("Presenting view controller should be accessible")
}
}
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let interruptableAnimator = interruptibleAnimator(using: transitionContext)

if type == .presentation {
if let chidoriMenu: ChidoriMenu = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as? ChidoriMenu {
transitionContext.containerView.addSubview(chidoriMenu.view)
}

if let presentingViewController = transitionContext.viewController(forKey: .from) {
presentingViewController.view.tintAdjustmentMode = .dimmed
} else {
preconditionFailure("Presenting view controller should be accessible")
}
} else {
if let presentingViewController = transitionContext.viewController(forKey: .to) {
presentingViewController.view.tintAdjustmentMode = .automatic
}
}

interruptableAnimator.startAnimation()
}

func interruptibleAnimator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating {
if let animatorForCurrentSession {
return animatorForCurrentSession
}

let propertyAnimator = UIViewPropertyAnimator(duration: transitionDuration(using: transitionContext), dampingRatio: 0.8)
propertyAnimator.isInterruptible = true
propertyAnimator.isUserInteractionEnabled = true

let isPresenting = type == .presentation

guard let chidoriMenu: ChidoriMenu = (isPresenting ? transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) : transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)) as? ChidoriMenu else {
preconditionFailure("Menu should be accessible")
}

let finalFrame = transitionContext.finalFrame(for: chidoriMenu)
chidoriMenu.view.frame = finalFrame

// Rather than moving the origin of the view's frame for the animation (which is causing issues with jumpiness), just translate the view temporarily.
// Accomplish this by finding out how far we have to translate it by creating a reference point from the center of the menu we're moving, and compare that to the center point of where we're moving it to (we're moving it to a specific coordinate, not a frame, so the center point is the same as the coordinate)
let translationRequired = calculateTranslationRequired(forChidoriMenuFrame: finalFrame, toDesiredPoint: chidoriMenu.summonPoint)

let initialAlpha: CGFloat = isPresenting ? 0.0 : 1.0
let finalAlpha: CGFloat = isPresenting ? 1.0 : 0.0

let translatedAndScaledTransform = CGAffineTransform(translationX: translationRequired.dx, y: translationRequired.dy).scaledBy(x: 0.25, y: 0.05)
let initialTransform = isPresenting ? translatedAndScaledTransform : .identity
let finalTransform = isPresenting ? .identity : translatedAndScaledTransform

chidoriMenu.view.transform = initialTransform
chidoriMenu.view.alpha = initialAlpha

// Animate! 🪄
propertyAnimator.addAnimations {
chidoriMenu.view.transform = finalTransform
chidoriMenu.view.alpha = finalAlpha
}

propertyAnimator.addCompletion { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
self.animatorForCurrentSession = nil
}

animatorForCurrentSession = propertyAnimator
return propertyAnimator
}

private func calculateTranslationRequired(forChidoriMenuFrame chidoriMenuFrame: CGRect, toDesiredPoint desiredPoint: CGPoint) -> CGVector {
let centerPointOfMenuView = CGPoint(x: chidoriMenuFrame.origin.x + (chidoriMenuFrame.width / 2.0), y: chidoriMenuFrame.origin.y + (chidoriMenuFrame.height / 2.0))
let translationRequired = CGVector(dx: desiredPoint.x - centerPointOfMenuView.x, dy: desiredPoint.y - centerPointOfMenuView.y)
return translationRequired
}
}
Loading

0 comments on commit 6a80491

Please sign in to comment.