Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Swipe Transition
Search
Tatsuya Tanaka
January 24, 2018
Technology
1.9k
12
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swipe Transition
#potatotips 47
https://github.com/tattn/SwipeTransition
Tatsuya Tanaka
January 24, 2018
More Decks by Tatsuya Tanaka
See All by Tatsuya Tanaka
iPhoneのセンサー情報をmacOSアプリでリアルタイム活用するための技術
tattn
1
800
Better use of SwiftUI
tattn
0
520
Swift Concurrencyによる安全で快適な非同期処理
tattn
2
1.5k
iOSアプリの技術選択2022
tattn
7
4k
Widget Suggestions 対応と ヤフーの新OS対応
tattn
1
1.4k
WidgetKitで良い体験を作るには / Good experience with WidgetKit
tattn
2
2k
既存アプリにSwiftUIをどう組み込んでいくか
tattn
8
2.6k
iOS 14からのアプリ内課金
tattn
5
3.2k
iOS 14の位置情報系アップデート
tattn
0
23k
Other Decks in Technology
See All in Technology
転んだ話が背中を預ける理由になる / A_story_about_falling_down_gives_you_a_reason_to_watch_each_other_s_backs.pdf
pauli
3
320
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
870
IoTデバイスを繋げるプロトコルMatterをAndroidで使用する方法
harutiro
0
120
Lambda MicroVMsが分からなすぎたので使い所を1から考えてみた
tsukuboshi
2
420
Datadog の学び方 - あるいは、オブザーバビリティを学ぶとは何か
mananyuki
1
490
生成AIと進める探索的データ分析(2026.10.03 第122回Tokyo.R勉強会)
tatamiya
2
1.4k
Meet AgentCore Identity Consent Portal
hironobuiga
3
190
Snowflake Horizon Catalog と Apache Iceberg で作る オープンなデータ基盤
kitagawaz
0
450
Deep Data Security 機能解説
oracle4engineer
PRO
2
720
プロダクト価値を、 チームが使える判断軸に変える
vivion
0
130
子育てエンジニアの可処分時間が減っても成長を諦めない戦い方
sudoakiy
2
1.9k
1万名の社員が使う認証基盤で どう信頼性を担保するか?
kairim0
0
210
Featured
See All Featured
Practical Orchestrator
shlominoach
192
12k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
510
Everyday Curiosity
cassininazir
0
350
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
530
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
450
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
860
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Faster Mobile Websites
deanohume
310
32k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
260
Transcript
Swipe Transition #potatotips 47 ాத ୡ (@tattn)
• Yahoo!Ҋ • iOSΞϓϦΤϯδχΞ • GitHub: @tattn • Qiita: @tattn
• Twitter: @tanakasan2525 ాத ୡ (@tattn)
Α͋͘Δ ศརͳεϫΠϓδΣενϟʔ Λ࣮ͯ͠Έ·ͨ͠
ͲͷҐஔͰ εϫΠϓόοΫͰ͖Δ
ը໘ͷͲ͜ͰࠨʹεϫΠϓͰ͖Δ ը໘(Τοδ)Ͱͳͯ͘OK
Sloppy Swiping ͱݺΕ͍ͯ·͢ɻ ͜ͷεϥΠυͰγϯϓϧʹ SwipeBackͱදه͠·͢ɻ
ԼεϫΠϓͰϞʔμϧΛด͡Δ
ԼʹεϫΠϓ͢ΔͱϞʔμϧͷը໘͕εϫΠϓͱͱʹҠಈ͠ɺ ͋ΔఔεΫϩʔϧ͢Δͱด͡Δ
͜ͷεϥΠυͰ SwipeToDismissͱදه͠·͢ɻ
࣮ͯ͠Έ·ͨ͠ͷͰɺ ͦͷ࣮ํ๏Λ͝հ͠·͢
࣮ํ๏
ࠓճͷओͳొਓ • UIPanGestureRecognizer • UIViewControllerAnimatedTransitioning • UIViewControllerTransitioningDelegate • UINavigationControllerDelegate
• UIPercentDrivenInteractiveTransition
UIPanGestureRecognizer ࢦͷҠಈྔͳͲΛऔಘͰ͖ΔΫϥεɻ ࠓճ͜ΕͰεϫΠϓΛݕग़͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJQBOHFTUVSFSFDPHOJ[FS
UIViewControllerAnimatedTransitioning ࣗ࡞ͷը໘ભҠΛ࣮Ͱ͖Δϓϩτίϧɻ SwipeBackͰViewΛӈʹҠಈɺ SwipeToDismissͰViewΛԼʹҠಈ ͢ΔͨΊʹ༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJWJFXDPOUSPMMFSBOJNBUFEUSBOTJUJPOJOH
UIViewControllerTransitioningDelegate present/dismiss࣌ʹ Ͳͷτϥϯδγϣϯ(UIViewControllerAnimatedTransitioning)Λ ར༻͢Δͷ͔Λࢦఆ͢Δϓϩτίϧɻ SwipeToDismissͰࣗ࡞ͷը໘ભҠΛར༻͢ΔͨΊʹ ༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJWJFXDPOUSPMMFSUSBOTJUJPOJOHEFMFHBUF
UINavigationControllerDelegate UINavigationControllerͰൃੜ͢ΔΠϕϯτͷัଊ Ͳͷτϥϯδγϣϯ(UIViewControllerAnimatedTransitioning)Λ ར༻͢Δͷ͔Λࢦఆ͢Δϓϩτίϧɻ SwipeBackͰࣗ࡞ͷը໘ભҠΛར༻͢ΔͨΊʹ ༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJOBWJHBUJPODPOUSPMMFSEFMFHBUF
UIPercentDrivenInteractiveTransition ը໘ભҠͷิؒํ๏ͷࢦఆ ը໘ભҠ͕Կ%͍ྃͯ͠Δͷ͔ͳͲΛ ઃఆ͢ΔΫϥεɻ SwipeBackͱSwipeToDismissͰ Ͳ͜·ͰεϫΠϓͨ͠ͷ͔Λදݱ͢ΔͨΊʹ༻͠·͢ɻ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJUVJQFSDFOUESJWFOJOUFSBDUJWFUSBOTJUJPO
(ൃද࣌ؒͷؔͰ) SwipeBackͷํΛհ͠·͢ɻ (SwipeToDismiss΄΅ಉ࣮͡Ͱग़དྷ·͢ɻ)
SwipeBackAnimator class SwipeBackAnimator: NSObject, UIViewControllerAnimatedTransitioning { func animateTransition(using transitionContext:
UIViewControllerContextTransitioning) { guard let to = transitionContext.viewController(forKey: .to), let from = transitionContext.viewController(forKey: .from) else { return } let containerView = transitionContext.containerView containerView.insertSubview(to.view, belowSubview: from.view) to.view.frame = containerView.frame ભҠݩͷviewͷԼʹભҠޙͷviewΛinsert͍ͯ͠·͢ɻ SwipeBack࣌ʹԼͷViewΛදࣔ͢ΔͨΊͰ͢ɻ
͜ͷ෦
SwipeBackAnimator // ύϥϥοΫεޮՌ to.view.transform.tx = -containerView.bounds.width * 0.3 UIView.animate(
withDuration: transitionDuration(using: transitionContext), delay: 0, options: .curveLinear, animations: { to.view.transform = .identity from.view.transform = CGAffineTransform(translationX: to.view.frame.width, y: 0) }, completion: { _ in from.view.transform = .identity transitionContext.completeTransition( !transitionContext.transitionWasCancelled ) }) ભҠޙͷviewʹύϥϥοΫεޮՌΛ͚ͭͭɺ ભҠલͷviewΛӈҠಈ
SwipeBackNavigationController class SwipeBackNavigationController: UINavigationController { private let animator =
SwipeBackAnimator() private var interactiveTransition: UIPercentDrivenInteractiveTransition! override func viewDidLoad() { super.viewDidLoad() delegate = self let panGesture = UIPanGestureRecognizer() panGesture.addTarget(self, action: #selector(handlePanGesture(_:))) panGesture.maximumNumberOfTouches = 1 view.addGestureRecognizer(panGesture) } viewʹUIPanGestureRecognizerͱ UINavigationControllerDelegateΛηοτ
SwipeBackNavigationController extension SwipeBackNavigationController: UINavigationControllerDelegate { public func navigationController(_ navigationController:
UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { return operation == .pop ? animator : nil } public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return interactiveTransition } } ར༻͢Δࣗ࡞ͷτϥϯδγϣϯΛฦ͢ɻ (εϥΠυʹࡌͤΔͱਏ͍ݟͨͰ͕͢ɺ࣮͍ͯ͠Δͷ2ߦͰ͢)
SwipeBackNavigationController @objc private func handlePanGesture(_ recognizer: UIPanGestureRecognizer) { switch
recognizer.state { case .began: interactiveTransition = UIPercentDrivenInteractiveTransition() interactiveTransition.completionCurve = .linear popViewController(animated: true) case .changed: let translation = recognizer.translation(in: view) interactiveTransition.update(translation.x / view.bounds.width) case .ended: if recognizer.velocity(in: view).x > 0 { interactiveTransition.finish() interactiveTransition = nil } else { fallthrough } case .cancelled: interactiveTransition.cancel() interactiveTransition = nil default: break } } δΣενϟʔʹ߹Θͤͯঢ়ଶΛߋ৽
100ߦຬͨͳ͍ίʔυͰ γϯϓϧͳSwipeBackΛ࣮Ͱ͖·ͨ͠ɻ ࠓճͷ࣮ˣʹஔ͍ͯ͋Γ·͢ɻ https://github.com/tattn/SwipeTransitionExample
ϥΠϒϥϦԽ
͔ͤͬ͘ͳͷͰϥΠϒϥϦԽ͠·ͨ͠ https://github.com/tattn/SwipeTransition ScrollView͕͋ͬͯಈ࡞͢ΔΑ͏ʹͨ͠Γɺ Method SwizzlingͰશը໘ʹద༻͢Δػೳ͋Γ·͢ɻ SwipeTransition ͥͻɺ͓ࢼ͍ͩ͘͠͞ʂ
·ͱΊ
·ͱΊ ʘδΣενϟʔͰૉఢUXΛࢦͦ͏ʗ ʘʘ\\٩( 'ω' )و //ʗʗ ఏڙ͞Ε͍ͯΔΈΛར༻͢Δ͜ͱͰ ҙ֎ͱ؆୯ʹ࣮͢Δ͜ͱ͕ग़དྷ·ͨ͠