스크롤에 nscollectionView를 다시 그리기하면 그래픽이 분해됩니다
-
20-09-2019 - |
문제
나는 작은 자극제가있다 NSCollectionView
여기서 NSCollectionViewItem
창을 스크롤하면 시각적으로 분해됩니다.
해체 속도는 스크롤 속도에 따라 다릅니다. 예를 들어 천천히 스크롤하면 해체가 더 자주 발생합니다. 빠른 스크롤은 덜 스크롤합니다. 문제는 NSCollectionViewItem
나는 볼 수있는 프레임의 경계를 십자가를 사용하고 있습니다.
내 nsview (사용자 정의보기 NSCollectionViewItem
)는 매우 간단한 드로잉 알고리즘을 가지고 있습니다. 너무 복잡한 것은 없습니다.
기본적으로 DrawRect 메소드의 DirtyRect 내에 프레임을 생성하고 그 안에 몇 개의 프레임을 만듭니다.
-(void)drawRect:(NSRect)dirtyRect
{
NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);
NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);
NSBezierPath * mOuterFramePath = [NSBezierPath bezierPathWithRect:mOuterFrame];
NSBezierPath * mSelectedFramePath = [NSBezierPath bezierPathWithRect:mSelectedFrame];
NSBezierPath * mRedFramePath = [NSBezierPath bezierPathWithRect:mRedFrame];
NSBezierPath * mInnerFramePath = [NSBezierPath bezierPathWithRect:mInnerFrame];
[mainBackgroundColor set];
[mOuterFramePath fill];
if (selected)
[[NSColor yellowColor] set];
else
[mainBackgroundColor set];
[mSelectedFramePath fill];
if (isRedBorder)
[[NSColor redColor] set];
else
[mainBackgroundColor set];
[mRedFramePath fill];
[[NSColor blackColor] set];
[mInnerFramePath fill];
}
나는 초점을 잠그고 코드 전후에 릴리스를 시도했지만 그래픽 컨텍스트를 설정하고 복원하는 것만으로도 문제를 해결하는 것 같지 않습니다.
나는 스노우 레오파드를 사용하고 있습니다 - 그것이 차이를 만든다고 생각하는 것은 아닙니다.
솔루션 업데이트
여기에 관심이있는 사람은 NSREPONDER에서 권장하는 문제에 대한 해결책이 있습니다. 나는 초기를 만들고 있었다 mOuterFrame
에 기초한 drawRect:
행동 양식 dirtyRect
지적했듯이, 잘못된 일이었습니다. 빠른 변화 :
NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);
0 기반 기원 지점으로 :
NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);
또한 위의 코드 변경이 그 자체로 문제를 해결하기에 충분했지만 제안 된 바와 같이 사각형 만 사용하는 것처럼 코드의 효율성을 조정했습니다. 두 픽셀 라인을 얻기 위해 변경 사항을 추가해야했습니다. 새로운 방법 :
-(void)drawRect:(NSRect)dirtyRect
{
NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);
NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);
[NSBezierPath setDefaultLineWidth:2.0];
[mainBackgroundColor set];
[NSBezierPath strokeRect:mOuterFrame];
if (selected)
[[NSColor yellowColor] set];
else
[mainBackgroundColor set];
[NSBezierPath strokeRect:mSelectedFrame];
if (isRedBorder)
[[NSColor redColor] set];
else
[mainBackgroundColor set];
[NSBezierPath strokeRect:mRedFrame];
[[NSColor blackColor] set];
[NSBezierPath strokeRect:mInnerFrame];
}
해결책
가장 먼저 눈에 띄는 것은 NSFramerect () 및 nsrectFill ()을 대신 사용할 수있을 때 많은 경로를 만들기 때문에 위의 코드가 다소 낭비된다는 것입니다.
둘째, 그리기 한 내용의 형상은 -DrawRect로 전달 된 사각형에 의존해서는 안됩니다. 그 사각형은 단지 업데이트 영역이 무엇인지 알려주므로보기가 복잡한 경우 무엇을 그릴 지 결정하는 데 더 효율적일 수 있습니다.