Instructions icon indicating copy to clipboard operation
Instructions copied to clipboard

Cant handle frame changes for the current coachmark

Open diegodossantos95 opened this issue 1 year ago • 9 comments

Describe the bug

I have a coachmark on top of the keyboard, so I want to change the coachmark position based on the keyboard size. The issue is that the readme says that we should use the CoachMarkController.prepareForChange() and CoachMarkController.restoreAfterChangeDidComplete(), but those functions don't do anything on iOS 13 or later.

I found a possible workaround, which is to run flow.pause(). helper.updateCurrentCoachMark(), flow.resume(), but the resume function creates a new coachmark in the screen, so every frame change a new coachmark appears, and keeps the old ones visible.

To Reproduce

  1. Create coachmark using some view that will change the frame
  2. Call the prepareForChange function before changing the frame
  3. Update the highlight view frame
  4. Call restoreAfterChangeDidComplete function

Expected behavior

The coachmark should move to the new frame position.

Screenshots

The result of the workaround usage. Screenshot 2023-03-23 at 17 29 08

Environment

  • Device: iPhone 13 Pro
  • iOS version: 16.3.1
  • Instructions version: 2.2.0
  • Dependency Manager: SPM

diegodossantos95 avatar Mar 23 '23 20:03 diegodossantos95

Hey @diegodossantos95, thanks for reporting the issue! I think the README hasn't been updated, let me have a look.

ephread avatar May 03 '23 21:05 ephread

@ephread What is the right approach to update the Coachmark?

diegodossantos95 avatar May 04 '23 13:05 diegodossantos95

@diegodossantos95 your current approach sounds correct, but I need to know more about your flow.

  • When is the keyboard displayed? Does it appear in between two coach marks?
  • When do you call flow.pause(), is it in willShow?

ephread avatar May 05 '23 21:05 ephread

@ephread , the keyboard is always visible because the coach mark appears on the keyboard's toolbar. The keyboard's size changes when the user changes the keyboard layout, and I listen to this event to update the coachmark's highlight frame. I call the flow.pause() in the listener of keyboardDidShowNotification and keyboardDidHideNotification

diegodossantos95 avatar May 09 '23 00:05 diegodossantos95

@diegodossantos95 alright, thanks for the clarification, IIRC flow.pause() has undocumented limitations, can you try calling it in willShow instead?

ephread avatar May 11 '23 01:05 ephread

@ephread do you mean keyboardWillShowNotification? I tried and I got the same result: multiple coachmarks.

diegodossantos95 avatar Jun 06 '23 12:06 diegodossantos95

@diegodossantos95 I meant in the delegate's method (see here and there). Sorry, I should I been clearer.

ephread avatar Jun 08 '23 23:06 ephread

I tried, but it crashed because of simultaneous access of FlowManager.currentCoachMark on L221 FlowManager.coachMarksViewController.show(coachMark: &currentCoachMark!, at: currentIndex).

diegodossantos95 avatar Jun 09 '23 13:06 diegodossantos95

Simultaneous accesses to 0x600001496da0, but modification requires exclusive access. Previous access (a modification) started at ProjectFlowManager.currentCoachMark.modify + 41 (0x10c2c6419). Current access (a modification) started at: 0 libswiftCore.dylib 0x00007ff80d9fc540 swift::runtime::AccessSet::insert(swift::runtime::Access*, void*, void*, swift::ExclusivityFlags) + 442 1 libswiftCore.dylib 0x00007ff80d9fc7a0 swift_beginAccess + 66 2 Project 0x000000010c2c63f0 FlowManager.currentCoachMark.modify + 41 3 Project 0x000000010c2c8850 FlowManager.createAndShowCoachMark(afterResuming:changing:) + 2103 4 Project 0x000000010c2c9900 closure #1 in FlowManager.resume() + 65 5 Project 0x000000010c2c9420 FlowManager.resume() + 1211 6 Project 0x000000010ba92bd0 InstructionCoachMarkComponent.coachMarksController(:willShow:beforeChanging:at:) + 164 7 Project 0x000000010ba92cc0 protocol witness for CoachMarksControllerDelegate.coachMarksController(:willShow:beforeChanging:at:) in conformance InstructionCoachMarkComponent + 14 8 Project 0x000000010c297d30 CoachMarksController.willShow(coachMark:beforeChanging:at:) + 224 9 Project 0x000000010c2983c0 protocol witness for CoachMarksControllerProxyDelegate.willShow(coachMark:beforeChanging:at:) in conformance CoachMarksController + 15 10 Project 0x000000010c2c8850 FlowManager.createAndShowCoachMark(afterResuming:changing:) + 1255 11 Project 0x000000010c2c7920 FlowManager.showNextCoachMark(hidePrevious:) + 661 12 Project 0x000000010c2c6c20 closure #1 in FlowManager.startFlow(withNumberOfCoachMarks:) + 45 13 Project 0x000000010c28ef30 closure #1 in CoachMarksViewController.prepareToShowCoachMarks(:) + 646 14 Project 0x000000010c2c11b0 closure #2 in TranslucentOverlayStyleManager.showOverlay(:withDuration:completion:) + 1002 15 Project 0x000000010ba56cd0 thunk for @escaping @callee_guaranteed (@unowned Bool) -> () + 52 16 UIKitCore 0x000000012233da36 UIVIEW_IS_EXECUTING_ANIMATION_COMPLETION_BLOCK + 15 17 UIKitCore 0x000000012233da47 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 797 18 UIKitCore 0x000000012230d920 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 190 19 UIKitCore 0x000000012230def2 -[UIViewAnimationState animationDidStop:finished:] + 263 20 UIKit 0x0000000127b5e0dd -[UIViewAnimationStateAccessibility animationDidStop:finished:] + 195 21 QuartzCore 0x00007ff808948634 CA::Layer::run_animation_callbacks(void*) + 318 22 libdispatch.dylib 0x000000010b95cf53 _dispatch_client_callout + 8 23 libdispatch.dylib 0x000000010b96d79e _dispatch_main_queue_drain + 1463 24 libdispatch.dylib 0x000000010b96d771 _dispatch_main_queue_callback_4CF + 31 25 CoreFoundation 0x00007ff800386b66 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9 26 CoreFoundation 0x00007ff800380ad4 __CFRunLoopRun + 2482 27 CoreFoundation 0x00007ff8003804c7 CFRunLoopRunSpecific + 560 28 GraphicsServices 0x00007ff809c5c1ff GSEventRunModal + 139 29 UIKitCore 0x0000000121d1c249 -[UIApplication _run] + 994 30 UIKitCore 0x0000000121d214cc UIApplicationMain + 123`

diegodossantos95 avatar Jun 09 '23 13:06 diegodossantos95