CoreText is a very powerful system for laying out text in arbitrary ways. This is going to be a bit of a whirlwind tour of it to help out nonamelive on StackOverflow. I’m working on an advanced iOS book right now, and I’ll have a longer writeup there.
Read more…
For the last several months, all of my technical time not devoted to my primary employment has been absorbed in a little iPad project. Nights and weekends that I usually would spend writing blog posts, chatting on Stackoverflow, or working on PandoraBoy have instead been spent on one of the more interesting projects I’ve worked on. But now it’s front-page on apple.com, soaring up the charts, and I’m rolling onto other things. Top of my list, when not working on an awesome IM/Phone app full time, is starting work on a new iOS book, but close after that are PandoraBoy improvements, Cocoaphony and Stackoverflow. And maybe a little skiing. And there is that go-kart the family has started building. But still, blogging is up there, and I should have a new build of PandoraBoy out in the next week that fixes up some annoying bugs.
I’ve been playing with Core Text recently, and one of the things I wanted to do was layout text in an arbitrary CGPath. On Mac, you’d do this with NSLayoutManager, but iOS doesn’t have that so we have to build our own. I’ll discuss Core Text more later, but one of the steps along this problem is how to clip a CGRect to a CGPath. I found several discussions of finding CGPath intersections, all explaining the basic technique. Draw the things you care about into a bitmap context and then inspect the pixels to see where they overlap. Clear enough, but it was hard to find a small code sample that demonstrated this with Core Graphics.
For my purposes, I want the first full-height rectangle within the intersection of the line rectangle and the CGPath. Later I will expand this code to find all full-height rectangles within the intersection (there can be more than one), but this is enough to demonstrate the point.
Read more…
Several people have noted that PandoraBoy is displaying a “Profile” window over the player that interferes with the player. This is a notification from Pandora because they’ve changed their privacy settings (you can now make your profile private, and they want to know if you want that).
This should be a one-time event for existing accounts. I suspect that new accounts will not see it. The solution is to open www.pandora.com in Safari, answer the question, and then re-launch PB.
PandoraBoy goes directly to the the mini-player on launch. Pandora doesn’t code for that since it’s impossible from the website. So sometimes they make interfaces that are larger than the mini-player without updating the mini-player code to resize. PB doesn’t resize the window (it doesn’t know how large it should be). It just relies on the mini-player to do it in Javascript, but in cases like this, the mini-player also doesn’t know how large the window should be.
BTW, I often am asked why PB doesn’t make the window resizable for cases like this. The answer is that it doesn’t help. The mini-player is a flash app, and has a clipping frame independent of the window. So while you can resize the window, the content is still clipped at the border of the flash app. Ah, the wonders of Flash.
For those of you having trouble with Flash 10.1, I’ve fixed PB to handle it. This moves from the hackish “dig around in the NetscapePlugin objects and call undocumented methods” approach to a standard CGEvent based keyboard injection. You can’t use NSApp’s sendEvent: to talk to Flash (probably because Flash is not in Cocoa). But the following code is a good general purpose “send me a virtual keystroke.”
Read more…
Just a reminder, because the template doesn’t seem to set this up correctly. To build an Address Book action plugin for 10.6, you need to compile for x86_64 or it will silently not show up. If you plan to support 10.5, you’ll need i386 as well. The template seems to build 32-bit universal (i386, ppc) by default.
Based on a discussion from StackOverflow.
Sometimes you want to inject some logic into a method you don’t control. The most common sane reason to do this is for debugging or profiling. For instance, you might want to log every time the various NSNotificationCenter methods are called so you can determine if that’s a performance bottleneck. (As I discovered myself, if you have thousands of notification observations in your system, it can be a serious performance problem.)
In most OOP languages your only option would be to subclass the object you want to instrument and then arrange for every instance of that object to be your subclass. In many cases that’s either very difficult or outright impossible, particularly if the object is used internally by a system framework. But Objective-C is highly dynamic, and message dispatching is resolved at runtime. You can modify how it works.
Read more…
In the last post, we discussed how to wrap simple C++ objects in Objective-C. But how about more complex objects, particularly with shared_ptr? Read more…
Last year, I presented an approach to wrapping C++. Since then, I’ve been introduced to other approaches, particularly from gf who helped me better understand opaque objects. Since I do a lot of cross-language work, I’ve had some opportunity to play with and expand this, and so I’d like to update my C++ wrapping approach.
First, to remind everyone of the problem: you have a C++ object that you want to consume in Objective-C. That’s easy in ObjC++, but if you make an ivar that references a C++ class, then the header file can only be included by ObjC++ classes. This quickly spreads .mm files throughout your project, creating all kinds of headaches. ObjC is a beautiful thing, and C++ is fine, but ObjC++ is a crazy land that should be carefully segregated from civilized code. So how do we do it?
Read more…
Over the years I’ve travelled to China several times, and now I’m working with large group of developers in Suzhou, Hangzhou and Hefei. A few weeks ago I was able to visit again, and that’s gotten me back in the mood to study Chinese. It often helps me to write down things as I learn them, and some of my Chinese coworkers read this blog and might help set me straight as I wander through their language like a bull in a China shop (as it were….) It’s a bit off the trail for Cocoa development, so feel free to use the Subscribe2 link on the right to take this category off of your email subscription. Read more…