• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Scrolling NSTokenField -- Clips a little if resized quickly (see movie)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Scrolling NSTokenField -- Clips a little if resized quickly (see movie)


  • Subject: Scrolling NSTokenField -- Clips a little if resized quickly (see movie)
  • From: Jerry Krinock <email@hidden>
  • Date: Sat, 13 Jun 2009 12:07:44 -0700

In the list archives I've seen where others have wanted an NSTokenField in an NSScrollView, and have been stymied by the lack of access to the layout mechanism in NSTokenField. So I worked around this by adding tags one at a time, emulating the layout that NSTokenField must be doing. It's tedious, but works and doesn't hack into any Apple private methods. See code below.

There is one tiny problem. My scroll view autoresizes with its superview RBSplitSubview. If I slowly drag the split bar so as to decrease the split subview size until scrollers appear, all is fine. But if drag it quickly, the token field shifts upward so that part of its first row is clipped. A little Snapz Pro X movie is worth 10,000 words...

   http://sheepsystems.com/engineering/Tokenz.mov   (1.3 MB)

None of my code is running when this happens. You may notice that I have TinkerTool'ed my account to show scrollers on both ends of the scroll bar, but the same thing happens if I run on an un-tinkered Mac account. I've got Mac OS X 10.5.7. Does anyone have a possible explanation or workaround?

Thank you,

Jerry Krinock


**** This method may be put into an NSTokenField subclass or category. **** Invoke it method after setting the object value (tokens array).

**** Declaration ****

/*!
 @brief    Sizes the receiver's height to fit its current tokens in
 the current frame width, or the height of its enclosing scroll view,
 if one exists, whiever is greater.

@details Sizing is based on an interrow spacing of 2.0 which was
determined empirically since NSTokenField, unlike NSTableView, does
not make its interrow spacing accessible, and also the fact that
the interrow spacing seems to be independent of font size.&nbsp;
This has been tested with the token field's font size set to
-[NSFont systemFontOfSize:11.0] and -[NSFont systemFontOfSize: 11.0].&nbsp;
The code may need to be tweaked if Apple ever changes the layout
algorithm of NSTokenField.
*/
- (void)sizeHeightToFit ;



**** Implementation ****

- (void)sizeHeightToFit {
NSArray* allTokens = [self objectValue] ;
NSInteger allTokensCount = [allTokens count] ;
CGFloat availableWidth = [self frame].size.width ;
NSInteger nRows = 1 ;
NSInteger startingToken = 0 ;
NSInteger nTokensInThisRow = 0 ;
NSInteger nTokensPlaced = 0 ;
CGFloat height = 0.0 ;
CGFloat totalHeightWithOneRow = 0.0 ;
CGFloat tokenHeight ;
CGFloat interrowSpace = 2.0 ; // Determined empirically
while (nTokensPlaced < allTokensCount) {
NSRange tokenRange = NSMakeRange(startingToken, nTokensInThisRow + 1) ;
NSArray* currentRowTokens = [allTokens subarrayWithRange:tokenRange] ;
[self setObjectValue:currentRowTokens] ;
[self sizeToFit] ;
if (totalHeightWithOneRow == 0.0) {
totalHeightWithOneRow = [self frame].size.height ;
tokenHeight = totalHeightWithOneRow - interrowSpace ;
// Initial height: one token, plus space above, plus space below
height = (tokenHeight + 2 * interrowSpace) ;
}
CGFloat requiredWidth = [self frame].size.width ;
if (requiredWidth > availableWidth) {
nRows++ ;
if (nRows == 1) {
// This would only happen if the first token by itself was too wide
// to fit in a row, which would be very rare
height += (tokenHeight + 2 * interrowSpace) ;
}
else {
height += (tokenHeight + interrowSpace) ;
}
startingToken = startingToken + nTokensInThisRow ;
nTokensInThisRow = 0 ;
}
else {
nTokensInThisRow++ ;
nTokensPlaced++ ;
}
}


    [self setFrame:NSMakeRect(
                              [self frame].origin.x,
                              [self frame].origin.y,
                              availableWidth,
                              height
                              )] ;

    // Restore all tokens
    [self setObjectValue:allTokens] ;
}


_______________________________________________

Cocoa-dev mailing list (email@hidden)

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:
This email sent to email@hidden


  • Prev by Date: Re: SQLite -- same DB, different machines -> different results
  • Next by Date: trying to enable NSZombie, gdb can't find OSO file
  • Previous by thread: Re: How can I keep an NSPopUpButton open after the user selects a menu item?
  • Next by thread: trying to enable NSZombie, gdb can't find OSO file
  • Index(es):
    • Date
    • Thread