Resume UIView animation when app is resumed - xamarin.ios

I have a looping animation like this:
UIView.Animate(50, 0, UIViewAnimationOptions.Repeat | UIViewAnimationOptions.CurveLinear, () => {
bgBackground.Frame = new RectangleF(new PointF(-496, bgBackground.Frame.Y), bgBackground.Frame.Size);
}, () => {});
but when the app goes to background and the animation is not running.
I've listened for the event when the app comes to foreground but I can't figure out how to restart the animation.
I have another looping animation using CABasicAnimation and that one is still running when resuming the app so can't I use UIView based animations for looping animations?
Other similar questions have just provided CALayer animations as the solution:
How to pause and resume UIView Animation?
How to pause and resume UIView Animation (without Block Animation)?

I rewrote to use CABasicAnimation and then everything works great.
CABasicAnimation animSc;
animSc = CABasicAnimation.FromKeyPath("transform.translation.x");
animSc.From = NSNumber.FromFloat(0.0f);
animSc.To = NSNumber.FromFloat(-496.0f);
animSc.Duration = 50.0f;
animSc.RepeatCount = INFITE_NUMBER;
bgView.Layer.AddAnimation(animSc, "bg_anim");
And then I just call the above code when the view appears and everything starts animating again.

Related

Godot Won't Spawn Particles

I'm currently trying to make an explosion when a node hits the ground, but there's no explosion. I played the explosion scene and it works just fine. I tried spawning a different object and it works just fine. I checked the position of the explosion and it's the same as the body position. The explosion shows up in the inspector but not in game.
func _on_Ground_body_shape_entered(body_id, body, body_shape, local_shape):
print("collision")
var scene = load("res://Rock/Explosion.tscn")
var explosion = scene.instance()
add_child(explosion)
explosion.global_position = body.global_position
explosion.emitting = true
print(explosion.position)
print(body.position)
body.queue_free()
"load" isn't a thing, do var scene = preload("res://Rock/Explosion.tscn")

PixiJS - Not all touchend events triggering (outside of displayObject)

Pixijs (3.0.8) supports multi-touch as shown in their demos, and I've set up start, move and end listeners for touches on my mobile device.
The touches are registered on a square within the canvas which I'll call the interactiveArea, but the touchend events trigger when let go outside of the area as well. This is behavior that works fine with a single mouse cursor.
However, when using more fingers, having touches with the identifiers 0,1 and 2, only the first touchEnd is triggered outside of the area.
So I press and hold 3 fingers inside the interactiveArea and move them all outside of it. Then I let go of 1, and then the others. I won't be notified of touchEnds for event 0 and 2, and I'd have to re-register 3 touches and let go properly just to get a touchend for 2 triggered!
Any tips on how I can detect all touchends, rather than have it stop on the first touchend? I've tried working with a setTimeout hack as well, but that really doesn't suit my use case.
Edit I've made a basic codepen to demonstrate how touchendoutside is only triggered once. https://codepen.io/Thomaswithaar/pen/EygRjM Do visit the pen on mobile, as it is about touches rather than mouse interactivity.
Holding two fingers on the red square and then moving them out and letting go will only trigger one touchendoutside event.
Looking at the PIXI source code, there is indeed a bug in the Interaction Manager. Here is the method that processes touch end events:
InteractionManager.prototype.processTouchEnd = function ( displayObject, hit )
{
if(hit)
{
this.dispatchEvent( displayObject, 'touchend', this.eventData );
if( displayObject._touchDown )
{
displayObject._touchDown = false;
this.dispatchEvent( displayObject, 'tap', this.eventData );
}
}
else
{
if( displayObject._touchDown )
{
displayObject._touchDown = false;
this.dispatchEvent( displayObject, 'touchendoutside', this.eventData );
}
}
};
You can see in the else statement that a touchendoutside event gets dispatched when displayObject._touchDown is true. But after you release your first finger, it sets the flag to false. That is why you only receive that event once.
I've opened an issue here:
https://github.com/pixijs/pixi.js/issues/2662
And provided a fix here:
https://github.com/karmacon/pixi.js/blob/master/src/interaction/InteractionManager.js
This solution removes the flag and uses a counter instead. I haven't tested it yet, so please let me know if it works.

NSSplitViewItem collapse animation and window setFrame conflicting

I am trying to make a (new in 10.10) NSSplitViewItem collapse and uncollapse whilst moving its containing window so as to keep the whole thing "in place".
The problem is that I am getting a twitch in the animation (as seen here).
The code where I'm doing the collapsing is this:
func togglePanel(panelID: Int) {
if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
// Toggle the collapsed state
NSAnimationContext.runAnimationGroup({ context in
// special case for the left panel
if panelID == 0 {
var windowFrame = self.view.window.frame
let panelWidth = splitViewItem.viewController.view.frame.width
if splitViewItem.collapsed {
windowFrame.origin.x -= panelWidth
windowFrame.size.width += panelWidth
} else {
windowFrame.origin.x += panelWidth
windowFrame.size.width -= panelWidth
}
self.view.window.animator().setFrame(windowFrame, display: true)
}
splitViewItem.animator().collapsed = !splitViewItem.collapsed
}, completionHandler: nil)
}
}
I am aware of the "Don't cross the streams" issue (from session 213, WWDC'13) where a window resizing animation running on the main thread and a core animation collapse animation running on a separate thread interfere with each other. Putting the splitViewItem collapse animation onto the main thread seems like the wrong approach and I've got a nagging feeling there's a much better way of doing this that I'm missing.
Since I am not finding any documentation on the NSSplitViewItems anywhere (yet) I would appreciate any insights on this.
I have the little test project on GitHub here if anyone wants a look.
Update The project mentioned has now been updated with the solution.
Thanks,
Teo
The problem is similar to the "don't cross the streams" issue in that there are two drivers to the animation you've created: (1) the split view item (2) the window, and they're not in sync.
In the example from the '13 Cocoa Animations talk, constraints were setup to result in the correct within-window animation as only the window's frame was animated.
Something similar could be tried here -- only animating the window's frame and not the split view item, but since the item manages the constraints used to (un)collapse, the app can't control exactly how within-window content animates:
Instead the split view item animation could completely drive the animation and use NSWindow's -anchorAttributeForOrientation: to describe how the window's frame is affected.
if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
let window = self.view.window
if panelID == 0 {
// The Trailing edge of the window is "anchored", alternatively it could be the Right edge
window.setAnchorAttribute(.Trailing, forOrientation:.Horizontal)
}
splitViewItem.animator().collapsed = !splitViewItem.collapsed
}
For anyone using Objective C and targeting 10.11 El Capitan.
This did the trick for me, didn't need to set AnchorAttributes.
splitViewItem.collapsed = YES;

GTK3 GtkLayout with cairo, cannot get update region

I am trying to draw a GtkLayout using cairo. The layout is huge and I need to get the part that is visible in the container window and update that part only. With GTK2 the expose event data was sufficient to do this. I am not successful with GTK3.
In the function to handle "draw" events, I did the following:
GdkWindow *gdkwin; // window to draw
cairo_region_t *cregion; // update regions
cairo_rectangle_int_t crect; // enclosing rectangle
gdkwin = gtk_layout_get_bin_window(GTK_LAYOUT(layout));
cregion = gdk_window_get_update_area(gdkwin);
cairo_region_get_extents(cregion,&crect);
expy1 = crect.y; // top of update area
expy2 = expy1 + crect.height; // bottom of update area
The problem is that cregion has garbage. Either gdk_window_get_update_area() is buggy or I am not using the right drawing window.
Passing the GtkLayout as follows also does not work (this is the function arg for g_signal_connect):
void draw_function(GtkWidget *layout, cairo_t *cr, void *userdata)
Whatever gets passed is not the GtkLayout from g_signal_connect, but something else.
================= UPDATE ====================
I found a way to do what I want without using GtkLayout.
I am using a GtkDrawingArea inside a viewport.
I can scroll to any window within the large graphic layout
and update that window only. Works well once I figured out
the cryptic docs.
scrwing = gtk_scrolled_window_new(0,0);
gtk_container_add(GTK_CONTAINER(vboxx),scrwing);
drwing = gtk_drawing_area_new();
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwing),drwing);
gtk_scrolled_window_set_policy(SCROLLWIN(scrwing),ALWAYS,ALWAYS);
scrollbar = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrwing));

Is a timer mandatory for drawing OPENGL ES

I have a method called startAnimation:
-(void)startAnimation{
1: self.animationTimer=[NSTimer scheduledTimerWithTimeInterval:1/60
target:self selector:#selector(gameLoop)
userInfo:nil repeats:YES];
2: //[self gameLoop]
{
The gameLoop method is like this:
-(void)gameLoop{
[self updateModel];
[self render]
{
Now, a very strange thing happens. If I comment the line 1 and uncomment the line 2 in startAnimation method I will not get the objects rendered to my screen. I thought rendering might require continuously calling the gameLoop metod. But even if I set the timer to not repeat (so repats:NO) objects are drawn. It means calling the gameLoop method just once, but from an NStimer object is enough. But if I call the gameLoop method manually I do not get the objects drawn. I tried calling the method inside a loop which executes 100 times. It did not help either. Is there something special with the timers in regards with OPENGL?Sorry for the question if it's too immature.
It´s been some time since you asked but the problem there is that the time interval is set to 1/60, which is 0 because it´s using the integer division. You should use 1.0/60.0 instead.
A timer is not needed for OpenGL ES. For my drawing app the render method is called everytime the user touches the screen.
However, for games most developers use CADisplayLink to call the render or gameloop method instead of NSTimer, as CADisplayLink will call the render method each time the screen refreshes.
Setting up a CADisplayLink is done like the example below.
- (void)setupDisplayLink {
//this sets up the game loop to be called once each time the screen refreshes
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(gameLoop:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
Then the gameLoop should be setup as:
- (void)gameLoop:(CADisplayLink *)displayLink {
[self updateModel];
[self render];
}

Resources