I'm writing a slider style navigation in React Native, where you slide away the topmost item in a pile of cards and it (should) move to the bottom of the pile.
However, since there is no zIndex in React Native, only the order of elements, I'm having a hard time actually moving it to the back.
Given a collection of elements in {this.props.children}, how can I take the topmost element, move it to the back and re-render the component with the new order?
I have tried moving the children to the state and doing things like this:
this.setState({
children: this.state.children.push(this.state.children.shift())
})
But I've had no success. state.children is set to undefined in this case.
Is there a right way to rearrange elements since there is no zIndex?
Array.prototype.push() is an in-place method, which updates the array and does not return anything.
You can just call push() and this.setState({ children: this.state.children }). Instead of setState, you can also use this.forceUpdate() since the reference in the state doesn't really change.
Related
I am trying to implement swipe actions on ListView for each element. Whole view is AbsoluteLayout, with two GridLayouts: one acting as "foreground"(list element) and other as "background" (swipe actions). I want them both to have equal height of "foreground" (which is dynamic and differs for every list element).
I succesfully implemented this on Android - I call a method on layoutChanged event
onLayoutChanged(args: EventData) {
const foregroundNotificationTemplate = (<AbsoluteLayout>(args.object)).getChildAt(1);
const backgroundButtons = (<AbsoluteLayout>args.object).getChildAt(0);
backgroundButtons.height = foregroundNotificationTemplate.getActualSize().height;
}
This unfortunatelly is not working on iOS. I tried to access Frame and UiView, but with no success - it has height of background content.
Demo presenting the problem on Nativescript Playground:
https://play.nativescript.org/?template=play-ng&id=4LRwDC
You don't necessarily have to use AbsoluteLayout as you are animating the position with translate which is possible with any layout. So using GridLayout instead of AbsoluteLayout should solve your problem on both platforms and you may also get rid layoutChanged event for measuring height.
Also note that your ListView item template can not be dynamic, you should not use ngIf or anything that would alter the structure of the list item, use multiple templates instead.
For anyone looking for working solution, thats what Manoj proposed: https://play.nativescript.org/?template=play-ng&id=yXggcv
Say I have a main, top-level Scaffold with an appBar and and body.
I have a button in the appBar and in its onTap I do:
Navigator.push(
context,
new MaterialPageRoute(builder: (_) => new DogeWidget())
);
Now DogeWidget is also aScaffold, because I like the appBar's default rendering.
What's happening:
I see the DogeWidget slide from the bottom of the screen. It's a whole scaffold sliding, not just the body.
What I'd like to see:
The main appBar's contents change, its hamburger changes into a "back arrow". There is no slide from the bottom, just an ordinary fade.
I don't know if I should write this myself or is there something that Flutter can provide?
AFAICT, the Gallery does what I want (e.g. tap on the "typography" item) - behavior is different despite my code being an almost literate copy and paste. Why?
For a while we had a hack that made this happen by making the AppBar a Hero, but it was not a good implementation and caused more trouble than it was worth so we backed it out. That's probably what you're seeing.
There's no easy way to do this using Navigator with today's material framework, though you can certainly implement widgets on top of the widgets layer that do it if you want to. What you might be able to do though is implement it by having a Navigator inside the body of your MaterialApp, and then manually replacing the AppBar (maybe via a crossfade widget like AnimatedCrossFade).
Solving this properly is something we intend to do in due course but we are prioritising bugs and API stability at the moment so it is not something we plan to do in the near term (next few months).
Problem
I am having problems with my sortable list with several items of various height. The problem occurs when I'm trying to move a larger item to the first or last position (which both have smaller objects). If I succeed currently depends very much on where on the larger item I click and start dragging.
If I want to move the item to the smaller bottom position I must click close to the bottom of the item for it to work, and if I want to drag it to the top position I must click closely to the top. But I want to be able to drag the item by clicking anywhere.
Some additional information
The items cannot be dragged outside the parent and the parent is only as large as it has to be and a scroll appears if it's larger than it's container. So it seems that I cannot drag the larger item past the first(smaller) item if I don't drag it in the top part of the item.
I've been trying to fix this by using cursorAt and using top:0 and another test using bottom:0 But it doesn't seem to make any difference (so I might have misunderstood how to use it). I am currently using tolerance: pointer.
I can bypass the problem of not being able to drag the larger item to the last position by temporary during the sorting increasing the height with the height of the dragged item. But it doesn't always work and its not a very good solution. And the problem of not being able to drag it to the top still appears?
I cannot change the JQuery code as in jquery-sortable-with-containment-parent-and-different-item-heights
Question:
How can I drag a larger item to the top or bottom position while allowing the user to click anywhere on the item?
Thanks for your help!
This might not solve your problem, but I thought I'd share the results of some experimenting I did today. I needed to make a sortable photo gallery with inline-block pictures of varying widths, and found that moving wider photos would be really hard work because the placeholder was smaller than the item I was moving. I ended up using this:
container.sortable({
placeholder: "photo placeholder",
start: function (event, ui) {
ui.placeholder.width(ui.item.width());
}
});
The custom placeholder classes are there to ensure the placeholder isn't hidden by default, and the start event ensures that the placeholder is the same width as the item you're about to move. This worked very well for me, and in your case, substituting height for width might work.
I also tried using containment as you have done, and found that it sometimes makes things much harder depending on the items in the row. Like you have explained, including tolerance: "pointer" helps to alleviate the issues, but if possible, removing containment generally makes the UI more forgiving.
I have two Meteor.Collections in my app. One contains a bunch of "slider" objects, which define a title, max, min, base value, and step for each slider. Now, I have two problems. The first is making the sliders show up in the first place. I've tried to put the following code:
Sliders.find().forEach(function(slider) {
$("#"+slider._id).slider({
min:slider.min,
max:slider.max,
value:slider.base,
step:slider.step,
change:function(event,ui) {
Data.update({_id:Data.findOne({slider:event.target.id})._id}, {$set:{value:ui.value}});
}
});
});
in Meteor.startup, at the end of my client.js file, in a $(document).ready() block, and nothing seems to get it to work. When I paste it into the javascript console, however, it works. Anyways, that's my first problem.
My second problem is that whenever I slide the slider, the slider disappears. I can keep dragging the mouse around to change the value, but once I let go of the clicker, I can't change the value anymore. I've tried using the above way and calling a Meteor.method that changes it on the server side. It's the fact that I'm updating a collection that is published to the same client that makes the slider disappear. Anything short of that doesn't cause it to disappear. How should I deal with this?
Thanks!
Have you already tried using the Template.preserve method? http://docs.meteor.com/#template_preserve
I have this tool tip that is created every so often. What is the appropriate actionscript etiquite?
A. To Create and remove the tooltip moveclip when needed?
or
B. To hide and show the tooltip movieclip when needed?
With these A and B, the answer is B, because creating and then removing an object a lot of times creates a lot of garbage in the memory, which eventually leads to garbage collector calls, that slow your SWF's performance. You can easily go with a single tooltip MC, just fill it with information that corresponds to the new mouse coordinates before you show it.
There is another question, not so straightforward as yours, about how to hide and show a movie clip, either via visible property or via addChild() and removeChild() (AS3 only). If you are using AS2 or AS1, use visible property to hide and show your tooltip.
There are three ways to hide something in Actionscript : Alpha, visible and remove child.
Apha: If you turn the alpha zero the renderer always comes to this displayObject and renders it at alpha zero. So the object is always rendered you just cannot see it.
Visible == false In this case the object still exists in your displaylist. So the renderer comes to the object. Sees it's property is false and leaves it but it still exists in the display list.
removeChild This means that you're removing the object from the display list. This means that the renderer never had to even check for it. Which makes it the fastest option.
addChild doesn't take that much computing power as visible check. I'm sure you can find benchmarks on this.
If you don't have a lot of objects on yours screen and the tooltip is there every second I'd go with visible is false. In all other cases go with the third option.
On a side note, I've found it always easier to manage them with a toolTipManager. A class that makes sure that you have one tooltip on the screen because usually users only use one tooltip. So that makes things easier for me. I just always create the necessary tooltips and add them to the displaylist when required and remove them. (Not recreate them) At the same time have only one tooltip on stage.