Check if SKCameraNode view contains a node of a certain class? - ios

The SKCameraNode has two methods to it for checking node visibility inside it's viewport. (.containsNode() and .containedNodeSet())
The first return a bool, which is what I'm looking for. Checking for one node object works fine.
if myCamera.containsNode(mySpriteNode) == false {}
But I want to check wether it contains nodes of a class.
if myCamera.containsNode(MyClass()) == false {}
Since it doesn't work I wonder how this would be done.
Thank you.

You need to look at the other method you mentioned containedNodeSet(). This will return Set<SKNode> which you can then inspect as you wish, for example:
for node in cameraNode.containedNodeSet() {
if let interestingNode = node as? InterestingClass {
// Do something useful here
}
}

Related

What is a less verbose way to repeatedly pop() items from a vector?

When using a vector as a stack (storing states which are pushed and popped).
while stack.len() != 0 {
let state = stack.pop().unwrap();
// ... optionally push other states onto the stack.
}
Is there a less verbose way to do this in Rust?
You can use the fact that pop() returns an Option<T> and match on that using a while let loop:
while let Some(state) = stack.pop() {
// ... fine to call stack.push() here
}
The while let desugars to something like the following:
loop {
match stack.pop() {
Some(state) => {
// ... fine to call stack.push() here
}
_ => break
}
}
Just to offer an alternative approach, you can also use the drain method to remove elements and give them to you in an Iterator.
stack.drain(..).map(|element| ...and so on
or
for element in stack.drain(..) {
//do stuff
}
You can also provide a RangeArgument if you only want to remove a certain range of elements. This can be provided in the form of <start-inclusive>..<end-exclusive>. Both the start and end of the range argument are optional and just default to the start of end of the vector, so calling drain(..) just drains the entire vector, while drain(2..) would leave the first 2 elements in place and just drain the rest.

Filtering: Exclude based on comparing two objects

I have a site where you can look for print shops on a map and filter what services they offer. Example is here: www.pigments.io
Each print shop has some properties stored in an object.
marker: {
processes: {
'digital': false,
'offset': false,
'silk': true,
'letterpress': false,
'engraving': false
},
finishings: {
'diecutting': true,
'lasercut': false,
'perforation': false,
'msg': false,
'softtouch': false,
},
products: {
'apparel': true,
'largeformat': false
}
}
The checkboxes return an object with the same structure, if the checkbox is checked the value is set to true. Now let's say if I want to only show silk screen shops if only silk screen has been checked under processes I could do something like this:
((marker.processes.silk == true && marker.processes.silk == formData.processes.silk) ||
The shop (marker) needs to be set to true with it's silk property & if the checkbox is checked it returns true. I'm using polymer, it filters over each marker object and evaluates the statement above. If it's true, it shows the marker. (I just realized I could have just done this:
((marker.processes.silk == true && formData.processes.silk == true))
Now of course I could do something like this.
((marker.processes.silk == true && formData.processes.silk == true) || (marker.processes.digital == true && formData.processes.digital== true))
and so on. That'll get ugly but it would theoretically work. But now if I introduce another field to be compared, say the finishings, I'm just getting completely lost here. Basically let's say I want to show only silk screen shops. Works as the code above. Now I only want to show the silk screen shops that do diecutting. I know how I could seperately look for only silk shops, or only diecutting shops. But now if I add those two, if diecutting is selected, this needs to exclude from the already filtered silk shops.
My brain is mushy, please help x_x. I've been trying to come up with the solution for this for over an hour, thoughts revolving in circles. I'm not even sure if this can be done with basic comparison operators anymore?
Also, I realize this approach is really ugly and inefficient.
/edit1:
I've just realized I should check underscore. Essentially if I'm not mistaken I just need to check if the print shop object's true values are the same as the checkbox object's values, right?
/edit2:
I think I need to get all the true properties from the marker object and compare them with the corresponding properties in the checkbox. If they are all true/identical, then the marker should be shown, right?
/edit3:
I nearly have it (I think if I was correct with assumption from edit2).
var markerProcessKeys = lodash.keys(lodash.pick(marker.processes, lodash.identity));
var markerProcess = lodash.pick(marker.processes, lodash.identity);
// doesn't work
var filterProcess = lodash.pick(formData.processes, markerProcessKeys);
//var filterProcess = lodash.pick(formData.processes, 'digital','offset');
// This one works, manually selecting only the true ones.
//So what's left to do is get the key names of the true ones and then compare
//I don't have it working yet though... I need to do the manual one automatically with lodash. Suggestions?
// this won't work
var = lodash.pick(markerProcess, filterProcess);
console.log(lodash.isMatch(t1, t2));
/edit4:
Nope, that's the wrong approach :/
Start by building a function that will tell you if a given shop matches a set of requirements. Assuming you requirements object looks like
{
processes: {
'digital': true
},
finishings: {
'diecutting': true
}
}
your function could be written as nested _.every calls :
function matches(requirements, shop) {
return _.every(requirements, function(properties, cat) {
return _.every(properties, function(val, key) {
// (!val) is there to ignore properties set to false
return (!val) || shop.marker[cat][key];
});
});
}
You would then use _.filter to extract the desired shops:
var validshops = _.filter(shops, _.partial(matches, requirements));
And a demo http://jsfiddle.net/nikoshr/9eq6o96L/

run function depending on passed integer in swift

I want to run different functions depending on selected level Integer
so if selected level is 1 then runfunc1(), if 2 then runfunc2()...
I know this is possible using if else
if levelselected == 1 {
runfunc1()
} else if levelseletecd == 2 {
runfunc2()
// ... and so on
}
Is there any better way than this, perhaps something like this
runfunc%i(),levelselected // I know its not correct but something similar
I dont want to write new code for every level, so any better way?
You can use something like:
var levelSelected = 0 //
var selector = Selector("runFunc\(levelSelected)")
if self.respondsToSelector(selector) {
NSThread.detachNewThreadSelector(selector, toTarget: self, withObject: nil)
}
You could have an array or dictionary of functions. A dictionary might be nicer since the logic for checking if the level is valid is a lot simpler:
let funcs = [1: runfunc1, 2: runfunc2]
if let funcToRun = funcs[levelselected] {
funcToRun()
}
However, you won't be able to easily dynamically build a function name from strings and numbers without using #objc functionality.
(except in the sense that you could make the key to the dictionary a string of the function name, but you still have to build the dictionary using actual function names determined at compile time)
That said, you can add to the funcs variable from elsewhere in the code so it does mean to can "hook up" new levels without changing this dispatching logic.
Not the exact solution you are looking for but this can make it easier :
Declare an array of the desired functions:
var levelFunctions: [()->()] = [runfunc1, runfunc2, runfunc3]
This syntax declares an array of functions that have zero argument and return nothing. You initialize this array with the required function names and then execute the desired function using the levelselected variable:
levelFunctions[levelselected]() // Or levelselected-1 if the variable is not zero-based
EDIT:
As Airspeed Velocity mentioned in the comment and his answer you should make sure the level is in the array bounds.
I prefer to create a function, for example runFuncFromLevel::Int -> (() -> Void). runFuncFromLevel return a proper function that you need.
func runFuncFromLevel(level: Int) -> () -> Void
{
switch level
{
case 1: return runfunc1
case 2: return runfunc2
default: return {}
}
}

What is the recommended way to break out of a block or stop the enumeration?

So, I just realize that break is only for loop or switch.
Here's my question: Is there a recommended way to break out of a block? For example:
func getContentFrom(group: ALAssetsGroup, withAssetFilter: ALAssetsFilter) {
group.enumerateAssetsUsingBlock { (result, index , stop) -> Void in
//I want to get out when I find the value because result contains 800++ elements
}
}
Right now, I am using return but I am not sure if this is recommended. Is there other ways? Thanks folks.
return is fine, block concept is similar to function, so returning is okay.
If you want to stop the current iteration of the enumeration, simply return.
But you say:
I want to get out when I find the value because result contains 800++ elements
So, that means that you want to completely stop the enumeration when you find the one you want. In that case, set the boolean value that the pointer points to. Or, a better name for that third parameter would be stop, e.g.:
func getContentFrom(group: ALAssetsGroup, withAssetFilter: ALAssetsFilter) {
group.enumerateAssetsUsingBlock() { result, index, stop in
let found: Bool = ...
if found {
//I want to get out when I find the value because result contains 800++ elements
stop.memory = true
}
}
}

Type True/False in Umbraco

We want to implement a check box[Type : true/false] in an DocumemtType in Umbraco.
Our current Project necessity is:
an check box which will decide whether an image should be an link or popup
The code goes this way ...
var child= #Model;
if(child.GetProperty("popUp").Value.ToString() == "1")
{
// true means image will act as popup
}
else
{
// false means image will act as link
}
But the problem is an error is occurred "Cannot perform runtime binding on a null reference"
I have also tried code like ,
if (child.GetProperty("popup").Value.Equals("1"))
{
}
or
if (child.GetProperty("popup").Value.ToString().Equals("1"))
{
}
but still not able to get it. All suggestions are welcomed .
node.GetProperty("popUp") is the way to go. If your control value is actually string, then your check logic would look like
if (node.GetProperty<string>("popUp") == "1"){}
Effectively generic GetProperty is what your code does, but it handles the null case, returning default(string).
(I have never used the dynamic thing, in case something will go wrong there, do the typed var node = new Node(id);)
Since you recently added the property to the document type, unless each node of that type has been published, the property will return null. You'll need to check if the property is null first then check if its true.
var popUp = child.GetProperty("popUp");
if (popUp != null && popUp.Value.Equals("1"))
{
// popup...
}
else
{
// link...
}
Used the below code and it worked fine for me
var child= #Model;
if(#child.popUp)
{
// true means image will act as popup
}
else
{
// false means image will act as link
}
Use this:
var child= #Model;
if(child.GetPropertyValue<bool>("popUp", false))
{
// true means image will act as popup
}
else
{
// false means image will act as link
}

Resources