Skip to content

Instantly share code, notes, and snippets.

@ziggythehamster
Created November 30, 2011 22:30
Show Gist options
  • Save ziggythehamster/1411426 to your computer and use it in GitHub Desktop.
Save ziggythehamster/1411426 to your computer and use it in GitHub Desktop.
@ziggythehamster's #Titanium #Sucks Proofs

@Appcelerator #Titanium #Sucks no. 1: Child view wider than a parent view breaks out of the parent. It should get cut off by the parent.

Diagram

If you have a box that's 40x40, and position another 40x40 box within it, with top=20 and left=20, you expect to see a 40x40 box containing a 20x20 box, not two 40x40 boxes.

Titanium sucks because...

If you put a view within a view on any widget toolkit, HTML, etc. and then move the subview around within its parent, the subview should never extend beyond the boundaries of its parent. That is, it should be clipped by its parent. At least by default. This is all OK if it's supposed to work this way, but several Q&A posts suggest this exact method as a way to crop a photo. So did it get broken at some point? Are there not unit tests to determine when behavior like this is reversed? Is some way that I'm inserting this view causing it not to work consistently? Why do I see code that is exactly equal to mine that supposedly works, but doesn't?

@Appcelerator #Titanium #Sucks no. 2: No equivalent of CSS's background-position property.

Since a background is only ever stretched, maybe this isn't a valid complaint. If a background image wasn't stretched to fit the container, this would be a nice feature.

Titanium doesn't suck but the situation sucks because...

We couldn't implement the UI effect we wanted to implement.

@Appcelerator #Titanium #Sucks no. 4: You can't make Toasts on Android unless you know the undocumented API to do so.

  • Toasts are a useful feature. You might use them to notify the user that we're still doing something and the app isn't frozen.
  • But they're not documented. I grepped the sourcecode for anything that uses the Android Toast object and got a hit.
  • The method is Ti.UI.createNotification even though it's Android-specific and ought to be Ti.UI.Android.createToast or something. So even if it were documented, it would be hard to figure out what method to use to make a toast appear.

@Appcelerator #Titanium #Sucks no. 3: Several choices for layout exist. Zero of them are documented.

  • Most UI toolkits have a "HBox" and a "VBox", which are extremely helpful in making layouts work across screens.
  • Titanium supports these layout modes (as a view property).
  • You don't know that just by reading the API docs. You have to read the wiki, too.

Titanium sucks because...

As I say for a later complaint, the documentation is abysmal.

@Appcelerator #Titanium #Sucks no. 5: No time picker on Android.

I was wrong about this. There IS a time picker on Android, but due to some ambiguous English in the documentation...

(Note that Titanium's Android implementation does not support the countdown timer or date+time varieties.)

...I was led to believe that it does not support countdown timer, date, time, or datetime varieties. In reality, it only doesn't support countdown timer and datetime varieties.

However, the useSpinner property, when set to true, doesn't make it behave exactly like an iPhone one (it won't be 320dp x 250dp-ish, for example, even if you set the width and height accordingly).

@Appcelerator #Titanium #Sucks no. 7: I spent a good 3 hours reproducing @jquerymobile's .fadeIn().fadeOut() in Ti, and it's slow/hacky :(.

@Appcelerator #Titanium #Sucks no. 6: Animations randomly don't work. Simple fade in, out, repeat. Worked around w/ interval that does it.

Essentially, the following jQuery is what I'm wanting to do (except, it doesn't work, and I have to resort to setTimeout and incrementing the opacity every 100ms):

var animate_view = true;

function actually_animate_view() {
    $(".whatever").fadeIn("slow").fadeOut("slow", function () {
        if (animate_view) {
            actually_animate_view();
        }
    });
}

Other operations will flip the animate_view flag. It should appear to pulsate when animate_view = true. Note that we would have to do something like this to actually animate:

if (!animate_view) {
    animate_view = true;
    actually_animate_view();
}

In Titanium, you SHOULD be able to do this:

var animate_view = true;

function actually_animate_view() {
    view.animate({ opacity: 1.0, duration: 1000 }, function() {
        view.animate({ opacity: 0.0, duration: 1000 }, function() {
            if (animate_view) {
                actually_animate_view();
            }
        });
    });
}

Problem is, on iOS, attempting to view.animate the second time (in the callback) causes the thing you're animating to wig out and blink and eventually settle at some value of opacity that is neither 1 nor 0. Additionally, any .animate() performed on that object will have zero further effect. And a bunch of garbage-to-me Objective C exceptions are spewed to my console at a rate of way-too-fucking-many-per-second. Something about the animation context being invalid.

Titanium sucks because...

Harvest time sheet

That's just one Thanksgiving Holiday week of dealing with this simple problem. Why didn't I post something to the Q&A site? I found example after example utilizing this chained animation method, and they're all exactly what I'm doing. They're animating properties other than opacity, so that could be the issue. But my employer hasn't paid for Titanium, so it's unreasonable to expect that, if it's a bug, that we'll get a fix in time for our deadline. Also, how does one answer a question along the lines of "this, this, this, and this do not function in my app though they're reported to work." without giving out too much source code, which I'm not authorized to do?

Obviously, paying for Titanium is an option, but when weighing the choices of paying for Titanium support and possibly having to wait on a hotfix (or not), or working around it in a quick and dirty way, sometimes quick and dirty wins. Also, sometimes, due to other issues (see number 9), you spend HOURS trying to make it work on Android.

@Appcelerator #Titanium #Sucks no. 8: bit.ly/spaqvH doesn't identify the items prop. Toolbars aren't tested in KitchenSink either.

  • Toolbars cannot be used in a normal way. That is, toolbar.add(button) is incorrect, and will result in you wondering why the buttons look wrong.
  • The correct way is to use the .items property, which can be set at runtime (possibly not while displayed?).
  • This is/was documented nowhere except possibly in the Kitchen Sink (I couldn't find it). Google came to the rescue.
  • This was noticed in April 2011 in version 1.5.

Titanium sucks because...

I have to Google to figure out how to properly use a particular widget. I come from a background of automatically generated RDocs, IntelliSense, and properties of objects being possible to introspect. Maybe I'm a bit harsh on this one; I can't expect every library to have every method documented I guess. But this is a product that Appcelerator expects to be commercially viable. Does purchasing Titanium provide me with documentation that's not abysmal?

@Appcelerator #Titanium #Sucks no. 9: Can't set a view's opacity at runtime on Android. NO FADE OUT FOR YOU! #soupnazi

  • Attempting to set .opacity on a view on Android does not work. The code is not hooked up in Java. You may only do it in the constructor.
  • This is a known issue (though not documented besides via the Q&A site) with a working workaround.
  • Expected behavior: it should set the opacity.

Workaround

if (Ti.Platform.name == "android") {
    view.animate({ opacity: desired_setting, duration: 1 });
} else {
    view.opacity = desired_setting;
}

Titanium sucks because...

opacity could be called a "core" property. It's something you can set on almost everything. Except, not on Android. For no other logical reason than they forgot to add it. And it went unnoticed for every version prior to 1.8. Also, the workaround does not work on iOS, so you have to check for Android specifically. I understand that it's not something worth backporting to 1.7, but at least they could mention this in the 1.7 API docs.

@Appcelerator #Titanium #Sucks no. 10: win.exitOnClose=true;win.close(); doesn't work. win.close(); leaves splash screen up, no way to exit.

  • Login window (heavyweight) appears.
  • win.close(); is NOT expected to exit the app (the login window will close when it is done and show the main app). exitOnClose cannot be used in the window's constructor for this reason.
  • Android back button press IS expected to exit the app.
  • Default behavior: The login window activity finishes, showing the Titanium splash screen activity. You cannot access this activity to hint that you want it to finish.
  • Expected behavior: The login window activity finishes. Titanium should detect there are no activities on the stack and finish the splash screen activity, thereby exiting.

Possible workarounds

  • Fuck it, Android users can't use their back button. return false;. Solution I used; makes me sad.
  • Put an event listener on the window's close event, make it finish the current activity (expected to be the splash screen). Doesn't work.
  • Above, but do it on the activity. Doesn't work.
  • Explicitly tell Titanium we want to exit. Untested because there is no documented method to do this, and Q&A articles indicate that there used to be but it was removed.
  • Access a global array of active activities and explicitly finish [0] when closing the app. Unsupported.

Titanium sucks because...

This is a very simple problem that should have a very simple solution. Pressing back should never show you the splash screen and/or the Ti.UI.backgroundColor. This is ridiculously easy to implement in PhoneGap and Android native.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment