-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
API for manually specifying views to animate #74
Comments
Currently, Hero requires a source root view, a destination root view, and a container view to animate these. Such API with lists of from/to views within one VC can be built though. There are some problem with handling view hierarchy, but should be possible. Glad to hear that someone is working with React Native. If you would like to continue working on it, I can provide this API in a few days. One thing to consider on your side, when animating in react, heroID shouldn't be used much. For existing views, you should know the destination state from react native and assign these as heroModifiers. These should be the fromViews. The toView list should be only the added views. The 'useNoSnapshot' modifier might also be useful. We can talk about this in detail if you wish to continue. Let me know. I am super excited about this! |
Don't worry about this too much for now! I am experimenting myself with a few things first and I'll let you know what I learn. I have something basically working but I'm still playing with how it should all work.
Yep, although I ran into one issue:
That's interesting. What I'm trying right now it to just give Hero the two native views that are controlled by react native, and let it take snapshots and simply animate the snapshots. Because the dest state has been applied to the real view, Hero can get it from there. I have a prototype working right now but I'll get back to you if this actually works. I will follow up with this later. This is for a client and the app isn't open-source, but I can extract what I figure out soon and talk about it with you. |
Checkout |
This is awesome! It's much closer to what we need. However, there seems to be a few tweaks needed. It looks like I need to clean up after the animations and call this code: self.hero.context.unhideAll()
self.hero.context.removeAllSnapshots(); I tried to do that in the completion callback but the hero context was already destroyed. So I had to tweak it to call the completion callback before destroying the context. Another thing is we lose out on the functionality of snapshotting the fullscreen and displaying a snapshot while beginning the animation. At least on the simulator, I could see the flickering, so I implemented the same code myself. This stuff: self.fullScreenSnapshot = containerView.window?.snapshotView(afterScreenUpdates: true) ??
fromRootView.snapshotView(afterScreenUpdates: true)
(containerView.window ?? containerView)?.addSubview(self.fullScreenSnapshot) However, I need to remove the snapshot before animating but there was no callback for that. So I also added an diff --git a/Sources/HeroBaseController.swift b/Sources/HeroBaseController.swift
index 91016fb..2de293c 100644
--- a/Sources/HeroBaseController.swift
+++ b/Sources/HeroBaseController.swift
@@ -345,22 +345,22 @@ internal extension HeroBaseController {
defaultAnimator = nil
progressUpdateObservers = nil
transitionContainer = nil
completionCallback = nil
container = nil
processors = nil
animators = nil
plugins = nil
- context = nil
beginTime = nil
progress = 0
totalDuration = 0
completion?(finished)
+ context = nil
}
}
// MARK: Plugin Support
internal extension HeroBaseController {
static func isEnabled(plugin: HeroPlugin.Type) -> Bool {
return enabledPlugins.index(where: { return $0 == plugin}) != nil
}
diff --git a/Sources/HeroIndependentController.swift b/Sources/HeroIndependentController.swift
index 0d94d1a..92057e5 100644
--- a/Sources/HeroIndependentController.swift
+++ b/Sources/HeroIndependentController.swift
@@ -18,24 +18,32 @@
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import UIKit
public class HeroIndependentController: HeroBaseController {
+ internal var animationCallback: (() -> Void)?
+
public override init() {
super.init()
}
- public func transition(rootView: UIView, fromViews: [UIView], toViews: [UIView], completion: ((Bool) -> Void)? = nil) {
+ public func transition(rootView: UIView, fromViews: [UIView], toViews: [UIView],
+ animation: (() -> Void)? = nil,
+ completion: ((Bool) -> Void)? = nil
+ ) {
transitionContainer = rootView
completionCallback = completion
+ animationCallback = animation
prepareForTransition()
context.defaultCoordinateSpace = .sameParent
context.set(fromViews: fromViews, toViews: toViews)
processContext()
prepareForAnimation()
+
+ animationCallback?()
animate()
}
} I'd open to other ways to solving this though. What do you think? It's so close! |
context should be kept nil before calling the completionCallback. This is so that the user can start another transition inside the completion. You can override inside the override func complete(finished: Bool){
context.unhideAll()
context.removeAllSnapshots();
super.complete(finished:finished)
} For the fullscreenSnapshot, not sure whats the best way. Maybe we can bake this logic inside |
I now agree that it's up to the user to implement the fullscreen snapshot. It may be nice to include that functionality in here but force the user to add/remove it, but I want to add it at a specific time (before invoking Hero) so it's nice that I control it. The only thing is that I need the animation callback to remove it. Thanks for the tip, I will try overriding |
@jlongster @lkzhao super exciting that you're working on this, is the WIP code up anywhere? Took a look at your fork (https://github.com/jlongster/Hero) but couldn't find the changes you were talking about above. |
@lkzhao @jlongster , any progress on this? Need this in RN. |
I'm working on an integration with React Native, and I'm at the point where I think I can get this working if I have one thing: a function that will start an animation given an array of from views an and array of to views. If you look at
Hero.start
, most of the code only deals these lists of views fromHeroContext
.Am I wrong in thinking that if on the React Native side I do all the work to figure out the from/to views, that I could get integration with Hero working if we provide that API? It would bypass parts of Hero that do the storyboard integration and automatically hooking up views, and only do the animations.
The text was updated successfully, but these errors were encountered: