tirsdag 22. november 2011

Beware of layers in iOS!

When working a MonoTouch application, I got a design that involved transparency, rounded corners and shadows. I was happy to discover that this could all be done via the layers property so I added a utility method:

public static void ApplyDropShadow (UIButton imgView)
{
  imgView.Layer.ShadowColor = UIColor.FromRGB (0, 0, 0).CGColor;
  imgView.Layer.ShadowOffset = new SizeF (2, 2);
  imgView.Layer.ShadowOpacity = 1f;
  imgView.BackgroundColor = UIColor.Clear;
  imgView.Layer.ShadowRadius = 1.0f;
  imgView.Layer.BorderColor = UIColor.White.CGColor;
  imgView.Layer.BorderWidth = 0.7f;
  imgView.Layer.CornerRadius = 2f;
  imgView.Layer.MasksToBounds = true;
  imgView.ClipsToBounds = false;
}
but this yielded "horrible" scrolling performance. Took me a good many hours to discover the cause of the "jerky" scrolling, but the shadow part was the culprit.

As a temporary solution the shadows are now gone, and I am now looking at doing this using CoreGrahics. Some sample code for MonoTouch can be found here: 
http://sabonrai.wordpress.com/2009/09/03/monotouch-sample-core-graphics-and-uiimageview/

objective-c: http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/

Another option is to buy an iPhone 4gs as the scrolling is silky smooth on this device.
Fragmentation! :-)

tirsdag 15. november 2011

Automating building of iOS apps

After 3 days of struggle and cursing I finally was able to automate our build process of iOS apps.

Since the scripts ended up as not very clean (for now) then I just want to point out the articles that helped me along the way:

For setting up the build script:
http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/

For automating Beta Builder
http://blog.flirble.org/2010/10/16/app-ad-hoc-beta-publishing/

Using those two scripts in combination and remembering to set the FTP transfer to binary (argh!) finally produced one beautiful looking IPA file that worked on my iPad! Now I just need to automate our Android apps but I suspect that will be much easier :-)

fredag 3. juni 2011

Android apps for tablets are broken

I am in the middle of coding an app for Android Honeycomb for a customer and I went through the sparse documentation on design guidelines. I then remembered having seen the CNN app on the Android 3.0 launch and thought I could use that for a reference design. I was wrong...

1. Launching the CNN app for tablets in portrait mode crashes the app. Everytime...
2. The top buttons in the right corner (action bar) have been customized so they look nothing like the standard Android 3.0 buttons.
3. Rotating the app to portrait isn't supported
4. Swiping sideways between articles are slow. Like really really slow.

I didn't want to drag down any particular app but the CNN app was so much marketed when Android 3.0 launched to I would think that they would fix these kind of bugs.

Also you cannot filter tablet apps on the Android Market (who got the idea that all apps are default compatible with tablets? Should be the other way around or at least mark tablet only apps in some way).

I really want to like Android tablets but as a owner of both the Xoom and the iPad2 I really can't see any reason for taking the Xoom with me on holidays. The Xoom drains the battery at least 5x faster than the iPad on standby (I can't find the apps that keeps the Xoom awake...). Aww I can't seem to stop finding faults with Android tablets. Android phones are great though! I still use my Nexus One even though I have an iPhone 4 :-)

torsdag 28. april 2011

MonoTouch.Dialog and sqlite-net not working together

MonoTouch.Dialog requires you to have all your fields as public fields (or else it will try to show your backing fields of your properties) while sql-lite wants properties to be able to use a class as a binding context.

The solution is very simple, just edit your MonoTouch.Dialog source code and change the method below to not include private fields when doing the reflection:

void Populate (object callbacks, object o, RootElement root)
  {
   MemberInfo last_radio_index = null;
   var members = o.GetType ().GetMembers (BindingFlags.DeclaredOnly | BindingFlags.Public |
               BindingFlags.Instance);