2010-06-10 4 views
1

확인이 항목은 정말 어려움이 있습니다. NSTextFieldCell을 함께 결합한 체크 박스를 만들고 싶습니다. 마우스가 텍스트가 아닌 상자를 친다면 체크 박스 이 켜짐이 중요합니다. 다소 많았지 만, 문제가 마우스 이벤트를 수신 중입니다. 한 행의 확인란을 하나만 클릭했기 때문에 모든 이벤트가 NSOnState로 바뀌었기 때문에 문제가 발생했습니다. 나는 을 사용하여 내가 수행 한 작업과 다양한 실패한 시도를 표시하고 이 작업을 수행합니다.마우스 클릭/마우스 이벤트를 처리하기 위해 NSButtonCell 인스턴스를 사용하여 사용자 지정 NSCell 가져 오기

그래서 이것은 내가 지금까지 그것을 한 적이 방법입니다

헤더 :

@interface MyCheckboxCellToo : NSTextFieldCell { 
    NSButtonCell *_checkboxCell; 
} 

구현 : 나는 아마 일을하지 말아야 알고

- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView { 
    NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil]; 
    NSLog(@"%@", NSStringFromPoint(point)); 

    NSRect checkFrame; 
    NSDivideRect(cellFrame, &checkFrame, &cellFrame, cellFrame.size.height/*3 + [[_checkboxCell image] size].width*/, NSMinXEdge); 

    if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) { 
     // the checkbox, or the small region around it, was hit. so let's flip the state 
     NSCellStateValue checkState = ([_checkboxCell state] == NSOnState) ? NSOffState:NSOnState; 
     [self setState:checkState]; 
     [_checkboxCell setState:checkState]; 
     [controlView setNeedsDisplay:YES]; 
     return NSCellHitTrackableArea; 
    }   
    return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];  
} 

:

거기
[self setState:checkState]; 
    [_checkboxCell setState:checkState]; 
    [controlView setNeedsDisplay:YES]; 

... becaus 결과적으로 매번 모든 체크 박스는 NSOnState로 이동합니다. 세포가 재사용 되었기 때문입니까? ImageAndTextCell은 어떻게 동일한 테이블 뷰에서 서로 다른 이미지를 가질 수 있습니까? 마우스 이벤트를 어떻게 처리합니까? 내가 시도

:

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame 
ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp { 
    NSLog(@"%s %@", _cmd, theEvent); 
    return [_checkboxCell trackMouse:theEvent inRect:cellFrame 
ofView:controlView untilMouseUp:untilMouseUp]; 
// return YES; 
// return [super trackMouse:theEvent inRect:cellFrame 
ofView:controlView untilMouseUp:untilMouseUp]; 
} 

- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView { 
    NSLog(@"%s %@", _cmd, NSStringFromPoint(startPoint)); 
    return [super startTrackingAt:startPoint inView:controlView]; 
} 

- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint 
inView:(NSView *)controlView { 
    NSLog(@"%s %@", _cmd, NSStringFromPoint(currentPoint)); 
    return [super continueTracking:lastPoint at:currentPoint 
inView:controlView]; 
} 

- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint 
inView:(NSView *)controlView mouseIsUp:(BOOL)flag { 
    NSLog(@"%s %d %@", _cmd, flag, NSStringFromPoint(stopPoint)); 
} 

trackMouse : ..., continueTracking : ...이 startTrackingAt

하지만

를 호출됩니다 않습니다 ... 그리고 stopTracking ... . "hit area"체크 상자를 클릭 할 때 호출되지 않음

trackMouse에서 ... 시도했습니다 ... 시도했습니다

return [_checkboxCell trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp]; 

return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp]; 

와도 마우스 이벤트는 체크 박스에 의해 처리되고이 발생할 것으로 보인다.

NSOnState로 이동하려면 어떻게하나요? 나는 내가 예쁘다고 알고있다. 그러나 많은 doc 독서와 google 검색 후에 나는 이것을 해결하는 데 성공했다. .

제안을 환영 의견 .. 여기 OK


객체의 생성과 파괴를 보여주기 위해 좀 더있다 ..

- (id)init { 
    if ((self = [super init])) { 
     _checkboxCell = [[NSButtonCell alloc] init]; 
     [_checkboxCell setButtonType:NSSwitchButton]; 
     [_checkboxCell setTitle:@""]; 
     [_checkboxCell setTarget:self]; 
     [_checkboxCell setImagePosition:NSImageLeft]; 
     [_checkboxCell setControlSize:NSRegularControlSize]; 

    } 
    return self; 
} 

- copyWithZone:(NSZone *)zone { 
    MyCheckboxCellToo *cell = (MyCheckboxCellToo *)[super copyWithZone:zone]; 
    cell->_checkboxCell = [_checkboxCell copyWithZone:zone]; 
    return cell; 
} 

- (void)dealloc { 
    [_checkboxCell release]; 
    [super dealloc]; 
} 
+0

확인란과 텍스트 필드가 모델 개체의 여러 속성을 참조하기 때문에 이러한 별도의 열을 만드는 것이 더 쉽습니다. (당신은 그것들을 어떻게 든 동일한 속성을 참조합니까?) –

+0

텍스트를 클릭하면 사용자가 항목을 선택하지 않아도 '탐색'할 수 있도록 기능을 분할합니다 (확인란이 수행함). – maz

답변

0

내가 직접 질문의 처리 - 이벤트 -에 - 세포 일부를 대답 할 수없는,하지만 난이 부분에 대답 할 수 있습니다 내가 아마 일을하지 말아야 알고

을 :

... 결과적으로 매번 모든 확인란이 NSOnState로 이동하기 때문입니다. 세포가 재사용 되었기 때문입니까?

UITableView가 UITableViewCells를 재사용하는 것과는 다른 의미로 재사용됩니다.

가 어떻게 ImageAndTextCell가 같은있는 tableview에 다른 이미지를 가질 수 올 (난 당신이 질문 "NSTableViewCell". 이러한 클래스는 AppKit의에 존재하지 않는합니다. 태그 것으로 나타났습니다)?

두 질문에 대한 답변은 같습니다.

UITableView는 각 행에 대해 하나의 셀을 사용하고 화면에 행이있는 셀 수만큼 많은 셀을 손에 쥐고 있지만 NSTableView는 모든 열에 대해 하나의 셀을 사용합니다.

각 열은 NSTableColumn 개체로 존재하며 각 NSTableColumn에는 정확히 하나의 셀 *이 있습니다. 테이블 뷰는 셀의 개체 값을 해당 열 - 행 교차에 대해 제공 한 값으로 설정 한 다음 해당 경계 내에서 적절한 위치에 그릴 것을 셀에 지시합니다. 동일한 셀을 사용하여 모든 열의 해당 열에 대해 동일한 작업을 수행합니다.

(애플은 특정 행에 대해 다른 셀을 사용할 수있는 기능을 추가했기 때문에 여기에 예외가 있습니다. 열이없고 다른 셀을 사용하는 그룹 행을 추가했기 때문입니다.)

솔루션을 만드는 데 도움이되지 못해 죄송합니다. (제 생각에는 별개의 항목을 제안하는 것 외에는) 미안하지만 최소한이 방법을 사용하면 도움이되기를 바랍니다. .

* 헤더 셀도 있지만 여기서는 계산하지 않습니다. 제가 말하는 정확히 "하나의 셀"은 데이터 셀입니다.

+0

안녕 피터, 질문에 신경을 써야한다면 당신이 나를 도울 수 있다면 나는 고맙게 생각합니다. 감사. 링크는 다음과 같습니다. http://stackoverflow.com/questions/31599502/nsbuttoncell-nsswitchbutton-doesnt-display-checked-box – Winston

0

[OK] 이것은 내 문제를 다소 수정 한 것으로 보입니다.

hitForTestEvent에서

: ...

대신

if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) { 
    // the checkbox, or the small region around it, was hit. so let's flip the state 
    NSCellStateValue checkState = ([_checkboxCell state] == NSOnState) ? NSOffState:NSOnState; 
    [self setState:checkState]; 
    [_checkboxCell setState:checkState]; 
    [controlView setNeedsDisplay:YES]; 
    return NSCellHitTrackableArea; 
}   

의 그것이 있어야 :

if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) { 
    [_checkboxCell setState:![_checkboxCell state]]; 
    return NSCellHitTrackableArea; 
}   

나는 아직도 내가 어떤에서 체크 박스 히트 영역을 클릭하면 몇 가지 문제가 자리가 등록되지 않지만 더 많거나 적은이 작동합니다.

0

NSTextFieldCell 대신 NSButtonCell의 하위 클래스 인 사용자 지정 셀 클래스를 만들었습니다. hitTestForEvent : inRect : ofView : 클릭이 체크 박스에없는 경우 0을 반환합니다.

NSBrowser 대리인의 브라우저에서 setboxValue : forItem : 확인란을 클릭하면 NSBoolean을 가져 와서 해당 "node"객체의 "checked"ivar를 해당 NSBoolean과 같게 설정합니다.

NSBrowser 위임자의 브라우저에서 : willDisplayCell : atRow : column : method 내 "노드"를 얻기 위해 [browser itemAtIndex :]를 호출하고 노드의 "checked"ivar를 사용하여 셀의 setState : 메소드를 호출합니다.

브라우저 위임자 항목에 대한 샘플 코드는 "ComplexBrowser"Xcode 샘플 프로젝트를 확인하십시오.

무엇을 하든지 NSBrowserCell의 서브 클래 싱을 권장하지 않습니다. 그것은 나를 위해 큰 막 다른 골목이었다.

업데이트 2011 년 8 월 30 일 : 이것은 10.5에서 작동하지 않습니다. 응. 나는 정사각형으로 돌아왔다.

관련 문제