Calculating the height of text in Android
While Android has numerous methods for sizing text, as far as I can see, none of them let you pass in a max width to get the height of the text once it wraps.
This is relatively simple to do on iOS via – sizeWithFont:constrainedToSize:lineBreakMode:.
For Android, I came up with the following convenience method to do it:
With this, you can just do
int height = getTextHeight("text", 160, 12.0f, Typeface.DEFAULT_BOLD); and you’re set.
Android Hardware Acceleration Bug: canvas.drawBitmap NullPointerException
Despite what Google says, there’s still a bug in the Android SDK when doing the following:
As per the Android docs, the second parameter is supposed to accept null. Passing in null works fine on devices without hardware acceleration, but will result in a crash if the device has HA. Google claims this bug was resolved in ICS, but it’s definitely still present as of today.
As long as you provide the src rect, everything works fine:
Webkit box-shadow inconsistencies
There appears to be an inconsistency in how Webkit renders the CSS3 “
box-shadow” tag depending on whether or not you prefix with “
John Barker brought this to my attention while working on something for Fav.tv so I began to investiate, and sure enough, it’s true:
You can find the code/working example here: http://jsfiddle.net/AK5Pt/2/
CSS3 Horizontal Navigation
Example of a pretty simple horizontal menu with vertical texted, purely powered by HTML and CSS3.
Head over to jsfiddle to see a working example and view the code: jsfiddle.net/qSzMa/4/
Note: This only contains the
-webkit css prefixes, you’ll need to update with
-ms, etc for production use.
“EGO” Xcode Theme for Xcode 4 + EGOv2
Almost two years ago now, we posted our Xcode theme, “EGO”. It’s been significantly more popular than I ever thought, we’ve seen a lot tweets about, we’ve seen it in screen casts, and it even made an appearance in the product launch video for robotcat’s Outside app. There’s no real metric for these things, but it seems to be one of the more popular third party Xcode things (we’re number one in Google!).
So, with the GM release of Xcode 4, we’ve gone ahead and ported our original EGO theme to the new Xcode 4 file format.
We’re also posting a new version of EGO, EGOv2. It’s based on EGO but has some key differences: New background color, new comment colors, themed console, and other minor tweaks and slight HSB adjustments. Here’s a comparison:
Original EGO Theme
New EGOv2 Theme
To install the themes, run the following blocks of code in Terminal:
mkdir -p ~/Library/Developer/Xcode/UserData/FontAndColorThemes; cd ~/Library/Developer/Xcode/UserData/FontAndColorThemes; curl -O http://assets.egoco.de/egotheme/EGO.dvtcolortheme
mkdir -p ~/Library/Developer/Xcode/UserData/FontAndColorThemes; cd ~/Library/Developer/Xcode/UserData/FontAndColorThemes; curl -O http://assets.egoco.de/egotheme/EGOv2.dvtcolortheme
Now just restart Xcode, go to Preferences > Fonts & Colors, and select “EGO” or “EGOv2” from the color theme drop down.
Note: Both themes now use Menlo Bold 13pt. This might not be for everyone, but I’ve found it much easier on the eyes and the bold seems to render nicer than regular, to me. Feel free to change!
Safari View Source in TextMate
While I love developing in Safari over alternatives like Firefox and Chrome, it lacks in one particular area: View Source. Safari’s View Source is practically useless, it doesn’t show line numbers, no syntax highlighting, etc.
Safari does offer the Web Inspect, which is nice, but a little annoying for quick look ups since everything is broken down into the DOM tree.
I’ve seen other Safari Extension’s like BetterSource that do this right in the browser, but really, why re-invent the wheel? TextMate is an awesome editor (albeit with this issues) and would be perfect for this.
I decided to see if I could get a “View Source in TextMate” item in the contextual menu. After reading over all of the docs, it became apparent to me that opening files in a native app just wasn’t going to happen.
I was able to get it to work by writing a TextMate plugin to handle the heavy lifting via it’s txmt:// URL scheme. So it all worked out in the end, you’ll just need to install the TextMate plugin as well as the Safari extension. Â Enjoy!
Download the ViewSourceInTextMate TextMate Plugin
Download the ViewSourceInTextMate Safari Extension
Facebook Redux: Who doesn’t love a happy ending?
Late last week, we had a bit of a misunderstanding with Facebook. We probably jumped the gun and ended up rendering the title of the post a bit hypocritical, as many of you pointed out. We should have reached out to Facebook first to find out how this happened, but we were pissed off and wanted to tell the world. It’s not easy to get in touch with Facebook, and we were in no mood to sift through their site to figure it out. Apparently, we could have emailed them at email@example.com.
As it turns out, Facebook didn’t even know they did anything wrong. EGOTableViewPullRefresh made it’s way into Three20 by way of a fork merge from a third party. This obviously doesn’t excuse Facebook, since they are responsible for their repository, but it does explain how it happened.
Within hours of our post going up, Jeff and David from Facebook’s Open Source team became aware of the mix up and reached out to us resolved the issue quickly. All in all, we were pretty happy with the resolution. We received credit for our code in three20, and we helped make Facebook’s iPhone app just a little bit better.
Facebook didn’t stop there though, David reached out to me again this week and send me a Facebook Swag Pack:
At the end of the day, Facebook screwed up, but did everything right to resolve it, and then went beyond that by sending us from free Facebook swag. We’re definitely sorry for how we initially handled this situation as well, since it’s clear now we could have avoided this by simply getting in touch with Facebook right away.
So thank you Facebook, you guys definitely have common courtesy!
What ever happened to common courtesy?
Updated 8:30PM — See below
Upon updating Facebook’s iPhone app last night, the first thing I immediately noticed was Pull to Refresh, the awesome UI Element created by Loren Brichter for Tweetie 2. We fell in love with this element the second Tweetie 2 hit app store, so we re-created it and open sourced it for everyone to use.
We’ve seen Pull to Refresh used in a few apps before and always wondered whether or not it was the one we created, but never one as popular as Facebook. I immediately started looking to see if our code made it into their app, it would be awesome to see Facebook using something we wrote.
I was a little disappointed when I found out this element was actually apart of their open source iOS library three20. Still, I was curious as to how they did it. Was it similar to what we came up? Was it better? We were never fully happy with our implementation, but never had the time to spend on making it better.
Digging through their source code, I finally found the class: TTTableHeaderDragRefreshView. I started looking over to code to see how they accomplished it, and that’s when I realized it: this was our class. You can see a diff on the two classes init methods below:
Note: For the purposes of the diff tool, I normalized the code blocks a bit, but you can compare for yourself by going here and here.
Facebook prefixed some variables, slapped their Three20 branding on it, restructured some code, but it was the same code we wrote. The same code we wrote, with zero mention of us.
Just like all of our open source code (and we’ve published a lot of it), our intent is always for it to be used to help developers and generally make apps/app store a better place for everyone. We were ecstatic that we might have made Facebook just a little bit better.
To find out that they took our code, re-released it as their own, and take credit for it though? That’s not cool Facebook. Not cool at all. It also violates our license, which states they need to retain our copyright notice when republishing it.
Still, we’re glad we could help made Facebook, three20, and all of the apps using pull to refresh in three20, better. It just would have been nice to get at least a hat tip from Facebook.
Update 8:30pm: Facebook reached out to us and they’ve updated their headers to attribute the source code to us.
How to Add Those @2x iOS4 Resources to SVN
In order for your app to take full advantage of the iPhone 4 Retina Display, you’ll need to add 2x resources to your iPhone project.
If you’re using SVN to manage your files, you’ll be faced with something pretty annoying:
$ svn add Default@2x.png
svn: warning: 'Default' not found
This was incredibly frustrating for me, no matter how I tried to escape it: single quotes, double quotes, backslashes, etc. SVN refused to add.
This is due to internal path recognizers in SVN. It expects the last at symbol to specify a revision. This is easily corrected by adding an at symbol to the end of your file:
$ svn add Default@2x.png@
A (bin) Default@2x.png
You’ll still need to manually add each resource, but it’s better than nothing. You could also use an IDE like Cornerstone, but I prefer the SVN CLI way of managing SVN.
Before anyone says anything: I know this isn’t an issue in GIT. GIT’s awesome, I love GIT. Unfortunately I still have some projects that require SVN.
What if images on the iPhone were as easy as HTML?
HTML is great, you want to set an image and you do <img src=”http://example.com/image.jpg” />. It does everything else for you, it caches, it even loads in the background. This is something that is taken completely for granted until you actually have to do it yourself.
The work involved in doing this on the iPhone is a pain. It’s not so bad if you’re viewing a single image, but if you’re displaying web-based images in a table view? Ugh.
We created EGOImageLoading to be as easy to use as HTML. EGOImageLoading is a few classes to make life easier on the developer, and to give the end user a much smoother result, easily.
Here’s what EGOImageLoading does:
- It loads the image in the background
- It caches the image to the disk for you
- It allows you to set a placeholder image while it’s loading
And here’s where it gets even more awesome: It changes loading priorities on the fly. If the user scrolls a bit in the table view, it’ll decrease the priority of those images, and load the ones they’re looking at right now, first.
So how simple is this? You can jump to our GitHub page and grab the demo, but here’s what our UITableViewCell subclass looks like:
Yeah, it really is that simple.
So how does it work?
It’s all based on EGOImageLoader and EGOCache.
We published EGOCache a few months ago, and we’ve since improved it to work better with EGOImageLoader.
EGOImageLoader does all the heavy lifting. It checks to see if the image is cached, if it is, you get it right away. If not, it loads it up in the background, and if it’s told to, it decreases the priorities and bumps new loads to the top.
You can use EGOImageLoader without table views, and it’ll work great. However, this post is all about table views, so we created UIImageView and UIButton subclasses, EGOImageView and EGOButton respectively, that interact with EGOImageLoader for you. That means all you have to do is initialize them, and set the URL. Seriously, that’s it.
They both contain “increaseImageLoadPriority” and “decreaseImageLoadPriority”.
You’ll probably never need to increase priority, since it does that for you when it loads (or re-sets a loading URL). However, you are going to want to decrease the load priority once the table view cell is moved off screen, we do this in the above example by tracking willMoveToSuperview.
So there you have it, image loading on the iPhone, that’s just as easy as throwing in an HTML image tag.
You can grab EGOImageLoading on it’s GitHub page: http://github.com/enormego/EGOImageLoading
Also a quick note, EGOImageLoader is powered by the awesome ASIHTTPRequest class by Ben Copsey. I’m sure you could rework it to work with NSURLConnection, but why? ASIHTTPRequest is amazing. If you’re not using it, you should be.
Update: When EGOImageLoading was first released, ASIHTTPRequest was a small, light weight class and the above was true. As ASIHTTPRequest grew it become increasingly bloated and unnecessary for most HTTP requests. EGOImageLoader is now powered by NSURLConnection.