UIGestureRecognizer on multiple view - xcode4

There is several examples on here about how to get multiple views recognized by a single UIGestureRecognizer. I have this code, and i've tried varies ways to get it work but unfortunately doesn't seem to work. I would appreciate it if one can shed some light on this.
the only way that i was able to get it to work if I create several (IBAction) functions but i have up to 100 views that need to be moved around so that would require to have 100 different functions. I read an example here where tag can be used to do just that but i tried it and unfortunately it does not work. I'm using XCode 4.6.1 if that helps. Here's the code below.
-(IBAction)handlePan:(UIPanGestureRecognizer *)recognizer{
UIView *player=recognizer.view;
int tag=player.tag;
[player addGestureRecognizer:recognizer];
if (tag!=0) {
CGPoint translation =[recognizer translationInView:self.view];
player.center=CGPointMake(player.center.x+translation.x, player.center.y+translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:player.superview];
}
}

It seems to me that you are adding the same gesture recognizer to the view that already has it. You could use a loop using the tag to add the UIPanGestureRecognizer to all your views and then in the method handlePan:(UIPanGestureRecognizer *)recognizer check which view is currently being panned and continue from there.

Related

Is it possible to show all options in Tokenize2?

Tokenize2 is a javacsript lib to select multiple options.
It provides a very neat UI to start writing and then get a list of options to select from. Selected options will show up as "tags" that can be removed with "x" link.
So far all is fine. But Right now you need to know what your looking for and start write at least one character to see matching alternatives.
In my scenario there are very few alternatives and they are not known to the user. I would like to show ALL options when the user clicks the input box. There is a configuration option named searchMinLength but it is already set to 0.
Is there a workaround that can be used? Maybe like triggering load and dropdown manually?
I know there are a lot of similar alternatives but I picked Tokenize2 because:
It looks clean and nice
It works in mobile browsers
I don't know if there is an "official" approach, but after some investigation I have found an acceptable workaround.
After downloading the Tokenizer2 sourceode I found the following line that triggered my attention:
if(this.input.val().length > 0){
this.trigger('tokenize:search', [this.input.val()]);
}
My interpretation is that the internal search command is not triggered unless the user input has at least one character. This line in sourcecode could easily be modified. I have filed a suggestion for this here: https://github.com/zellerda/Tokenize2/issues/26
My current workaround is to add an event listener for the select event and there trigger the internal search command. That works fine for my scenario and does not force a source code rewrite.
$("#my-dropdown").on("tokenize:select", function (e: Event, routedEvent: boolean) {
$("#my-dropdown").trigger('tokenize:search', "");
});
Tokenize2
This link worked for me GitHub
$('.tokenize-sample-demo1').on('tokenize:select', function(container){
$(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
});

Stackmob fetchExtended not working

I have started to use Stackmob as a backend for a simple app I am building.
In stackmob I have set a relationship between two schema's and want to use '.fetchExpanded' to grab all of the data from stackmob, see this fiddle (will need to view the console to see the output):
http://jsfiddle.net/mcneela86/65Rax/
.fetchExtended(1);
The same code works using the '.fetch' instead of '.fetchExpanded'.
Has anyone come across this before?
Would really appreciate any help.
Ok, I found a work around for this.
Instead of using '.fetchExtended(1);' I will just use '.fetch();' and when I am defining the model I will change the following:
var Bike = StackMob.Model.extend({
schemaName: "bikes"
});
to:
var Bike = StackMob.Model.extend({
schemaName: "bikes?_expand=1"
});
This seems to remove the need for '.fetchExtended(1);'
Hope this helps someone else.

How to setup durandaljs with Areas?

For the life of me I can't make durandaljs work with Areas. I'm developing an application with multiple mini SPAs, but I'm not sure how to set up durandaljs to work with it. I wasn't able to find anything online that can drive me in the right direction. The only similar question I found was this one, which is very vague.
My goal is to separate each SPA within it's own folder like so:
App
--areas
----area1
------viewmodels
------views
----area2
------viewmodels
------views
The router doesn't seem to have the concept of areas and no matter how I map the routes I get 404s when I call router.activate('page1'); after mapping with router.mapRoute('page1'); durandal is trying to get /App/viewmodels/page1.js.
Changing it to:
router.mapRoute('areas/area1/viewmodels/page1');
router.activate('areas/area1/viewmodels/page1');
results in another 404 fetching App/viewmodels/areas/area1/viewmodels/page1.js
I've also tried many other combinations which I no longer remember and can't seem to get it to work.
Can someone please post a working example of how to setup durandaljs with the router plugin and multiple mini SPAs (areas)? A link to an article document would also suffice.
You can use viewLocator.useConvention - maybe something like this:
viewLocator.useConvention(
"areas/area1/viewmodels",
"areas/area1/views",
"areas/area1/templates"
);
One good thing to realize is that useConvention() works in conjunction with any existing require.config paths setting. In other words, if you set the require.config so that "viewModels" and "views" are mapped to the right folders, then all is well.
For example, the code snippet above is functionally equivalent to:
window.require.config({
paths: {
"viewModels": "areas/area1/viewmodels",
"views": "areas/area1/views",
"templates": "areas/area1/templates"
}
viewLocator.useConvention("viewmodels", "views", "templates");
I a similar structure implemented in my application. I think that you have to put this piece of code, to do the viewLocator works properly.
viewLocator.useConvention(); //You can do that in you main.js
You can see more information here: http://durandaljs.com/documentation/View-Locator/
Also I recommed you to look the code of viewLocator.js, especially, the code of useConventionMethod.
Other possibility is to override the method convertModuleIdToViewId, to make it works as you want. But I think that using useConvention methos is enought.

Google maps API v3 - externally controlling radius on distanceWidget

this seems pretty specific to ask - but there was no other alternative to the expertbase of stackoverflow!
I'm stuck in a problem where I need to control the radius of the circle by an external means such as a dropdown or a textbox.
I had a hard time doing the circle and had to copy stuff from the Twitter search example on:
http://code.google.com/apis/maps/articles/mvcfun/twittersearch.html
Ideally, I would like to know how to bind an external even to the radiusWidget, the problem is - the sizer inside the radiusWidget seems a private entity.
It would be awesome if someone could hit me in the face with a bang!
Thx
distanceWidget.set('distance', XXX) should work. If you read the MVC article you can see how the binding is bi-directional.
You can look at the source of the Twitter example by downloading it to your computer, as you likely already did. When you have the source you can adapt it to your purposes as you like. The software usage rights (terms of usage, license, etc), if they are any, have to be respected of course.
In the case of the RadiusWidget you would just do:
function RadiusWidget(opt_distance) {
// ...
this.sizer = this.addSizer_(); // sizer is now accessible in RadiusWidget
}
RadiusWidget.prototype.addSizer_ = function() {
var sizer = ...
// ...
return sizer;
}

Are there solutions for streamlining the update of legacy code in multiple places?

I'm working in some old code which was originally designed for handling two different kinds of files. I was recently tasked with adding a new kind of file to this code. Most of my problems were solved by filling out an extensive XML file with a new entry that handled everything from what lists were named to how the file is written in plural lower case. But this ended up being insufficient, as there were maybe 50 different places in 24 different code files where I had to update hardcoded switch-statements that only branched for the original two file types.
Unfortunately there is no consistency in this; there are methods which operate half from the XML file, and half off of hardcode. Some of the files which look like they would operate off of the XML file don't, and some that I would expect that I'd need to update the hardcode don't need it. So the only way to find the majority of these is to run through testing the whole system when only part of it is operational, finding that one step to fix (when I'm lucky that error logging actually tells me what is going on), and then running the whole thing again. This wastes time testing the parts of the code which are already confirmed to work, time better spent testing the new parts I have to add on top of it all.
It's a hassle and a half, and to my luck I can expect that I will have to add yet another new kind of file in the near future.
Are there any solutions out there which can aid in this kind of endeavour? Something which I can input some parameters of current features, document what points in a whole code project actually need to be updated, and run something nice the next time I need to add a new feature to the code. It needn't even be fully automated, something that'll help me navigate straight to the specific points in everything and maybe even record what kind of parameters need to be loaded.
Doubt it matters specifically, but the code is comprised of ASP.NET pages, some ASP.NET controls, hundreds of C# code files, and a handful of additional XML files. It's all currently in a couple big Visual Studio 2008 projects.
Not exactly what you are describing, but if you can introduce a seam into the code and lay down some interfaces you can break out and mock, a suite of unit/integration tests would go a long way to helping you modify old code you may not fully understand well.
I completely agree with the comment about using Michael Feathers' book to learn how to wedge new tests into legacy code. I'd also strongly recommend Refactoring, by Martin Fowler. What it sounds like you need to do for your code is to implement the "Replace conditionals with polymorphism" refactoring.
I imagine your code today looks somewhat like this:
if (filetype == 23)
{
type23parser.parse(file);
}
else if (filetype == 69)
{
filestore = type69reader.read(file);
File newfile = convertFSto23(filestore);
type23parser.parse(newfile);
}
What you want to do is to abstract away all the "if (type == foo)" kinds of logic into strategy patterns that are created in a factory.
class FileRules : pReader(NULL), pParser(NULL)
{
private:
FileReaderRules *pReader;
FileParserRules *pParser;
public:
void read(File* inFile) {pReader->read(inFile);};
void parse(File* inFile) {pParser->parse(inFile);};
};
class FileRulesFactory
{
FileRules* GetRules(int inputFiletype, int parserType)
{
switch (inputFiletype)
{
case 23:
pReader = new ASCIIReader;
break;
case 69:
pReader = new EBCDICReader;
break;
}
switch (parserType)
... etc...
then your main line of code looks like this:
FileRules* rules = FileRulesFactory.GetRules(filetype, parsertype);
rules.read(file);
rules.parse(file);
Pull off this refactoring, and adding a new set of file types, parsers, readers, etc., becomes as simple as writing one exclusive to your new type.
Of course, go read the book. I vastly oversimplified it here, and probably got stuff wrong, but you should get the general idea of how to approach it from this. I can also recommend another book, "Head First Design Patterns", which has a great section on the Factory patterns (if you like those "Head First" kinds of books.)

Resources