On Wed, Dec 15, 2010 at 11:53 PM, Gideon King <gid...@novamind.com> wrote:
> Hi, I have a layer *hosting* view which has to use the geometryFlipped option 
> so that it behaves correctly, and need to add an NSTextView subview for 
> editing sometimes, and an ordinary custom view for editing at other times.

Ohhh, boy. :)

After a year and a half, many Radars, and at least one DTS incident
all spent dealing with layer-backed and layer-hosting views, I can
only make the professional recommendation that you avoid using Core
Animation for anything other than a convenient OpenGL scene graph
management API. Core Animation's interaction with AppKit is simply
broken. This is not to besmirch the hard work of David Duncan, et al.,
since this is a really hard problem. But at this point, I would be
equally happy with either of the following scenarios:

1. Apple fixes layer-backed and layer-hosting views and rewrites *all*
of AppKit with Core Animation to show that it can work. That means
replacing NSCells with CALayers and otherwise factoring their drawing
along the lines that a Core Animation user (or iOS developer) would
expect.
2. Apple narrows Core Animation's scope to high-performance 2D and
pseudo-3D OpenGL scene graph management, and removes layer backing
from the API entirely. Perhaps, instead, they could focus their 2D
acceleration back on QuartzGL.

> I am having trouble working out where to place the subview. It just seems to 
> end up in strange places.

You really don't have a layer-backed view. You have a layer-hosting
view, which is what you need if you want to play around with its
layers. Adding subviews to layer-hosting views is not supported
(there's a bunch of voodoo going on behind the scenes to support naïve
use of Quartz in a layer-backed context). David's suggestion to you
was the same advice given to us: create a layer-backed peer view to
your layer-hosting view in which to host your field editor and other
ancillary views.

> I have noticed also that the subview is drawing with reversed flippedness. I 
> am wondering if there is some workaround for this by either putting another 
> layer or view in between my layer and the overlay view? I have tried some 
> options but so far without success.

Flippedness is broken. rdar://problem/8009542

That is a categorical, unequivocal statement of fact. The layer
machinery cannot deal with views that return YES from -isFlipped. If
you follow David's advice, you will find that your view will scroll in
the opposite direction as intended, and will snap to bizarre sizes
when the scroll view is resized.

The only way I have found to fix that is to swizzle NSClipView's
implementation of certain methods to call private LayerKitGlue API.
Before the announcement of the App Store, this only worried me because
it might go away or otherwise break despite our best efforts to guard
against it. But now we're threatened with rejection for violating the
terms of the Mac App Store.

You will also need to deal with other undocumented behavior that
LayerKitGlue relies upon to do its job. For example, your override of
-resizeWithOldSuperviewSize: *must* call super's implementation, even
if you specifically want to avoid super's effects.
rdar://problem/8659667 Otherwise, you will get video garbage if you
live-resize a view.

Once you've got the layer geometry kinks worked out, there are some
issues with drawing layer contents. For example, NSLayoutManager
spellchecking is entirely broken. rdar://problem/8644121 It seems to
suffer similar confusion about flippedness; it draws the underlines as
if the graphics context is not flipped. It doesn't go through the
public -drawUnderlineForGlyphRange:… API to draw the red-dotted
underlines; there's a separate private API it uses (possibly to
facilitate background thread spell checking, though we have disabled
that).

That's assuming you're able to recite the magic incantation to get
subpixel antialiased text in the first place. For obvious reasons,
subpixel antialiasing requires opaque contents in the backing store in
order to do its job correctly. But merely filling your backing store
before drawing your text is not enough; you must create your own
CGBitmapContext with
kCGImageAlphaPremultipliedFirst|kCGBitmapByteOrder32Host in which to
do your drawing. There is no documentation indicating that this
combination of flags is required for subpixel antialiased text.

And when I say "merely filling your backing store," that of course
implies that you will mimic Core Animation's render process in order
to precompose the underlying layers into your opaque text-carrying
layers' backing stores, thus negating much of the benefit of using
Core Animation in the first place. And you will need to go through
great pains to match color spaces, or else your precomposed version of
colors will differ slightly but noticeably from that used by Core
Animation. There's no documentation about what color space Core
Animation operates in, but I think we've worked it out to be the same
as the window's color space. Regardless, we still have one
least-significant-bit of error between our drawing and Core
Animation's drawing. I imagine this error is unrecoverable.

Once you've finally got your view nice and pretty, do you plan on
printing it? If so, you're back in Quartz land anyway, unless you want
to blat a 72dpi bitmap to the printer. Which you don't. :)

> I see that a previous question along very similar lines was asked by Kyle 
> Sluder, but there didn't appear to be any replies to his question.

:)

> Any suggestions would be most welcome.

My professional suggestion: avoid using Core Animation for anything
related to traditional UI. CA is great for things like Front Row,
sprite-based animation/games, overlays atop Core Video movie playback,
data visualization (but be careful here! sometimes it's also the wrong
tool for building data visualization)... it's not good for writing the
next version of your productivity app's main content view.

--Kyle Sluder
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to