答案 0 :(得分:0)
以下是闪烁行的示例代码。不是动画本身。
@interface DTableView : NSTableView {
NSTrackingArea *trackingArea;
NSUInteger mouseHoverRow;
NSUInteger mouseHoverColumn;
NSUInteger lastHoverRow;
NSUInteger lastMouseHoverColumn;
NSUInteger flashRow; // temporary flash
DTableFlashType flashType;
BOOL flashToggle;
NSUndoManager *textEditUndoManager; // private mgr, separate from global document undoManager!
}
@property (assign, nonatomic) NSUInteger flashRow;
@property (assign, nonatomic) DTableFlashType flashType;
- (void)customDrawFlashRow:(NSRect)dirtyRect; // override point for subclassers
@end
@implementation DTableView
@synthesize flashRow;
@synthesize flashType;
-(void)awakeFromNib
{
flashRow = NSNotFound;
}
// override point for subclassers.
// the default implementation flashes flashRow, depending on
- (void)customDrawFlashRow:(NSRect)dirtyRect
{
///// NOTE! customDrawFlashRow is overridden by Director DScenesView
if ( flashRow != NSNotFound )
{
NSRect rowFrame = [self frameOfCellAtColumn:0 row:flashRow];
if ( NSIntersectsRect(rowFrame, dirtyRect) )
{
rowFrame.origin.x = dirtyRect.origin.x;
rowFrame.size.width = dirtyRect.size.width;
if ( flashType == kDTableFlashYellow )
{
flashToggle = !flashToggle;
if ( flashToggle ) [[NSColor whiteColor] set];
else [[NSColor yellowColor] set];
}
else
[[NSColor whiteColor] set];
NSFrameRect(rowFrame);
}
}
}
- (void)drawRect:(NSRect)dirtyRect
{
//getCpuCyclesMark();
sVisRectIncrement++; // invalidate cache
sDoingDrawRect = true;
[super drawRect:dirtyRect];
[self customDrawFlashRow:dirtyRect]; // overridden by Director DScenesView
sDoingDrawRect = false;
}
- (void)setFlashRow:(NSUInteger)iRow // note: DScenesView overrides this
{
// first, deal with previous flashRow if applicable
if ( flashRow >= 0 && flashRow < [self numberOfRows] )
{
NSRect rowFrame = [self frameOfCellAtColumn:0 row:flashRow];
rowFrame.origin.x = [self visibleRect].origin.x;
rowFrame.size.width = [self visibleRect].size.width;
[self setNeedsDisplayInRect:rowFrame];
}
flashRow = iRow;
if ( flashRow >= 0 && flashRow < [self numberOfRows] )
{
NSRect rowFrame = [self frameOfCellAtColumn:0 row:flashRow];
rowFrame.origin.x = [self visibleRect].origin.x;
rowFrame.size.width = [self visibleRect].size.width;
[self setNeedsDisplayInRect:rowFrame];
}
}
在我的控制器类中:
[toScenesTable setFlashRow:row];
[self performSelector:@selector(endFlash:) withObject:self afterDelay:0.2]; // :@selector(endFlash)
和endFlash:selector
- (void)endFlash:(id)sender
{
[toScenesTable setFlashRow:NSNotFound];
//[toScenesTable setSelectionHighlightStyle:0];
}
答案 1 :(得分:0)
以下是我添加的NSTableView类别方法,它以有用的方式滚动,大约25%来自顶部。
#pragma mark NSTableView category
@implementation NSTableView (VNSTableViewCategory)
-(NSInteger)visibleRow
{
NSRect theRect = [self visibleRect];
NSRange theRange = [self rowsInRect:theRect];
if ( theRange.length == 0 )
return -1;
else if ( NSLocationInRange( [self editedRow], theRange ) )
return [self editedRow];
else if ( NSLocationInRange( [self clickedRow], theRange ) )
return [self clickedRow];
else if ( NSLocationInRange( [self selectedRow], theRange ) )
return [self selectedRow];
else
return theRange.location + (theRange.length/2);
}
-(NSRange)visibleRows
{
NSRect theRect = [self visibleRect];
NSRange theRange = [self rowsInRect:theRect];
return theRange;
}
-(void)scrollRowToVisibleTwoThirds:(NSInteger)row
{
NSRect theVisRect = [self visibleRect];
NSUInteger numRows = [self numberOfRows];
NSRange visibleRows = [self rowsInRect:theVisRect];
//NSUInteger lastVisibleRow = NSMaxRange(visibleRows);
if ( NSLocationInRange( row, visibleRows ) )
{
if ( row - visibleRows.location < (visibleRows.length * 2 / 3) )
{
// may need to scroll up
if ( visibleRows.location == 0 )
[self scrollRowToVisible:0];
else if ((row - visibleRows.location) > 2 )
return;
}
}
NSRect theRowRect = [self rectOfRow:row];
NSPoint thePoint = theRowRect.origin;
thePoint.y -= theVisRect.size.height / 4; // scroll to 25% from top
if (thePoint.y < 0 )
thePoint.y = 0;
NSRect theLastRowRect = [self rectOfRow:numRows-1];
if ( thePoint.y + theVisRect.size.height > NSMaxY(theLastRowRect) )
[self scrollRowToVisible:numRows-1];
else
{
[self scrollPoint:thePoint]; // seems to be the 'preferred' method of doing this
// kpk note: these other approaches cause redraw artifacts in many situations:
// NSClipView *clipView = [[self enclosingScrollView] contentView];
// [clipView scrollToPoint:[clipView constrainScrollPoint:thePoint]];
// [[self enclosingScrollView] reflectScrolledClipView:clipView];
// [self scrollRowToVisible:row];
// [[[self enclosingScrollView] contentView] scrollToPoint:thePoint];
// [[self enclosingScrollView] reflectScrolledClipView:[[self enclosingScrollView] contentView]];
}
}