gpt4 book ai didi

objective-c - 禁用 NSView 的淡入淡出动画 `setHidden:`

转载 作者:行者123 更新时间:2023-12-03 17:53:05 28 4
gpt4 key购买 nike

我正在开发一个具有可拖动控件概念的项目,除了 NSView 在调用 setHidden: 时似乎采用淡入/淡出动画之外,一切都工作正常。

我已经能够通过将行 session.animatesToStartingPositionsOnCancelOrFail = YES; 更改为 NO 并使用自定义动画 NSWindow 子类自行实现图像快照来解决该问题。看起来很棒,但我知道一定有更简单的方法。

我已经尝试过:

  1. setHidden: 调用周围使用 NSAnimationContext 进行分组,持续时间为 0
  2. 使用控件和 super View 上的各种键(alpha、hidden、isHidden)设置 View 动画字典
  3. 覆盖控件及其 super View 的 animationForKey:

我没有使用 CALayers,甚至尝试将 wantsLayer: 明确设置为 NO。

有人知道如何禁用此动画,或者有比我的动画 NSWindow 更简单的解决方案吗?

这是我经过精简修改的代码,只需最少的代码即可了解我在说什么。

@implementation NSControl (DragControl)

- (NSDraggingSession*)beginDraggingSessionWithDraggingCell:(NSActionCell <NSDraggingSource> *)cell event:(NSEvent*) theEvent
{
NSImage* image = [self imageForCell:cell];
NSDraggingItem* di = [[NSDraggingItem alloc] initWithPasteboardWriter:image];
NSRect dragFrame = [self frameForCell:cell];
dragFrame.size = image.size;
[di setDraggingFrame:dragFrame contents:image];

NSArray* items = [NSArray arrayWithObject:di];

[self setHidden:YES];
return [self beginDraggingSessionWithItems:items event:theEvent source:cell];
}

- (NSRect)frameForCell:(NSCell*)cell
{
// override in multi-cell cubclasses!
return self.bounds;
}

- (NSImage*)imageForCell:(NSCell*)cell
{
return [self imageForCell:cell highlighted:[cell isHighlighted]];
}

- (NSImage*)imageForCell:(NSCell*)cell highlighted:(BOOL) highlight
{
// override in multicell cubclasses to just get an image of the dragged cell.
// for any single cell control we can just make sure that cell is the controls cell

if (cell == self.cell || cell == nil) { // nil signifies entire control
// basically a bitmap of the control
// NOTE: the cell is irrelevant when dealing with a single cell control
BOOL isHighlighted = [cell isHighlighted];
[cell setHighlighted:highlight];

NSRect cellFrame = [self frameForCell:cell];

// We COULD just draw the cell, to an NSImage, but button cells draw their content
// in a special way that would complicate that implementation (ex text alignment).
// subclasses that have multiple cells may wish to override this to only draw the cell
NSBitmapImageRep* rep = [self bitmapImageRepForCachingDisplayInRect:cellFrame];
NSImage* image = [[NSImage alloc] initWithSize:rep.size];

[self cacheDisplayInRect:cellFrame toBitmapImageRep:rep];
[image addRepresentation:rep];
// reset the original cell state
[cell setHighlighted:isHighlighted];
return image;
}
// cell doesnt belong to this control!
return nil;
}

#pragma mark NSDraggingDestination

- (void)draggingEnded:(id < NSDraggingInfo >)sender
{
[self setHidden:NO];
}

@end

@implementation NSActionCell (DragCell)

- (void)setControlView:(NSView *)view
{
// this is a bit of a hack, but the easiest way to make the control dragging work.
// force the control to accept image drags.
// the control will forward us the drag destination events via our DragControl category

[view registerForDraggedTypes:[NSImage imagePasteboardTypes]];
[super setControlView:view];
}

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp
{
BOOL result = NO;
NSPoint currentPoint = theEvent.locationInWindow;
BOOL done = NO;
BOOL trackContinously = [self startTrackingAt:currentPoint inView:controlView];

BOOL mouseIsUp = NO;
NSEvent *event = nil;
while (!done)
{
NSPoint lastPoint = currentPoint;

event = [NSApp nextEventMatchingMask:(NSLeftMouseUpMask|NSLeftMouseDraggedMask)
untilDate:[NSDate distantFuture]
inMode:NSEventTrackingRunLoopMode
dequeue:YES];

if (event)
{
currentPoint = event.locationInWindow;

// Send continueTracking.../stopTracking...
if (trackContinously)
{
if (![self continueTracking:lastPoint
at:currentPoint
inView:controlView])
{
done = YES;
[self stopTracking:lastPoint
at:currentPoint
inView:controlView
mouseIsUp:mouseIsUp];
}
if (self.isContinuous)
{
[NSApp sendAction:self.action
to:self.target
from:controlView];
}
}

mouseIsUp = (event.type == NSLeftMouseUp);
done = done || mouseIsUp;

if (untilMouseUp)
{
result = mouseIsUp;
} else {
// Check if the mouse left our cell rect
result = NSPointInRect([controlView
convertPoint:currentPoint
fromView:nil], cellFrame);
if (!result)
done = YES;
}

if (done && result && ![self isContinuous])
[NSApp sendAction:self.action
to:self.target
from:controlView];
else {
done = YES;
result = YES;

// this bit-o-magic executes on either a drag event or immidiately following timer expiration
// this initiates the control drag event using NSDragging protocols
NSControl* cv = (NSControl*)self.controlView;
NSDraggingSession* session = [cv beginDraggingSessionWithDraggingCell:self
event:theEvent];
// Note that you will get an ugly flash effect when the image returns if this is set to yes
// you can work around it by setting NO and faking the release by animating an NSWindowSubclass with the image as the content
// create the window in the drag ended method for NSDragOperationNone
// there is [probably a better and easier way around this behavior by playing with view animation properties.
session.animatesToStartingPositionsOnCancelOrFail = YES;
}

}
}
return result;
}

#pragma mark - NSDraggingSource Methods
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
switch(context) {
case NSDraggingContextOutsideApplication:
return NSDragOperationNone;
break;

case NSDraggingContextWithinApplication:
default:
return NSDragOperationPrivate;
break;
}
}

- (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
{
// now tell the control view the drag ended so it can do any cleanup it needs
// this is somewhat hackish
[self.controlView draggingEnded:nil];
}

@end

最佳答案

View 层次结构中的某个位置必须启用一个图层,否则不会有淡入淡出动画。这是我禁用此类动画的方法:

@interface NoAnimationImageView : NSImageView

@end

@implementation NoAnimationImageView

+ (id)defaultAnimationForKey: (NSString *)key
{
return nil;
}

@end

关于objective-c - 禁用 NSView 的淡入淡出动画 `setHidden:`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19869265/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com