NstextfieldCell이 수직 중앙 텍스트를 그릴 수있는 "올바른"방법이 있습니까?
-
22-07-2019 - |
문제
나는있다 NSTableView
여러 텍스트 열이 있습니다. 기본적으로 dataCell
이 칼럼은 Apple의 인스턴스입니다 NSTextFieldCell
모든 종류의 멋진 일을 수행하지만 셀의 상단에 맞는 텍스트를 그립니다. 텍스트가 세포에 수직으로 중앙에있는 텍스트를 그립니다.
내부 플래그가 있습니다 NSTextFieldCell
그것은 텍스트를 수직으로 수직으로 중심하는 데 사용될 수 있으며 아름답게 작동합니다. 그러나 내부 깃발이기 때문에 Apple은 사용이 제재되지 않으며 향후 릴리스에서 경고없이 사라질 수 있습니다. 나는이 내부 플래그가 간단하고 효과적이기 때문에 현재 내부 플래그를 사용하고 있습니다. 애플은 분명히 그 기능을 구현하는 데 시간을 보냈으므로 그 기능을 재 구현한다는 아이디어를 싫어합니다.
그래서; 내 질문은 이것입니다 : Apple의 nstextfieldcell과 똑같이 행동하는 것을 구현하는 올바른 방법은 무엇입니까?
레코드의 경우 여기에 내 현재 "솔루션"이 있습니다.
@interface NSTextFieldCell (MyCategories)
- (void)setVerticalCentering:(BOOL)centerVertical;
@end
@implementation NSTextFieldCell (MyCategories)
- (void)setVerticalCentering:(BOOL)centerVertical
{
@try { _cFlags.vCentered = centerVertical ? 1 : 0; }
@catch(...) { NSLog(@"*** unable to set vertical centering"); }
}
@end
다음과 같이 사용 :
[[myTableColumn dataCell] setVerticalCentering:YES];
해결책
다른 답변은 여러 줄에 효과가 없었습니다. 따라서 처음에는 문서화되지 않은 것을 계속 사용했습니다 cFlags.vCentered
속성이지만 앱 스토어에서 내 앱을 거부했습니다. 나는 여러 줄, 단어 포장 및 잘린 마지막 줄에 작동하는 Matt Bell의 수정 된 버전을 사용하게되었습니다.
-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
NSAttributedString *attrString = self.attributedStringValue;
/* if your values can be attributed strings, make them white when selected */
if (self.isHighlighted && self.backgroundStyle==NSBackgroundStyleDark) {
NSMutableAttributedString *whiteString = attrString.mutableCopy;
[whiteString addAttribute: NSForegroundColorAttributeName
value: [NSColor whiteColor]
range: NSMakeRange(0, whiteString.length) ];
attrString = whiteString;
}
[attrString drawWithRect: [self titleRectForBounds:cellFrame]
options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin];
}
- (NSRect)titleRectForBounds:(NSRect)theRect {
/* get the standard text content rectangle */
NSRect titleFrame = [super titleRectForBounds:theRect];
/* find out how big the rendered text will be */
NSAttributedString *attrString = self.attributedStringValue;
NSRect textRect = [attrString boundingRectWithSize: titleFrame.size
options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin ];
/* If the height of the rendered text is less then the available height,
* we modify the titleRect to center the text vertically */
if (textRect.size.height < titleFrame.size.height) {
titleFrame.origin.y = theRect.origin.y + (theRect.size.height - textRect.size.height) / 2.0;
titleFrame.size.height = textRect.size.height;
}
return titleFrame;
}
(이 코드는 ARC를 가정합니다. Attrstring.MutableCopy를 사용한 후 자동 제출을 추가합니다. 수동 메모리 관리를 사용하는 경우)
다른 팁
NSCELL의 우선 -titleRectForBounds:
그렇게해야합니다 - 이것이 셀에게 텍스트를 그릴 위치를 알려주는 방법입니다.
- (NSRect)titleRectForBounds:(NSRect)theRect {
NSRect titleFrame = [super titleRectForBounds:theRect];
NSSize titleSize = [[self attributedStringValue] size];
titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
return titleFrame;
}
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
NSRect titleRect = [self titleRectForBounds:cellFrame];
[[self attributedStringValue] drawInRect:titleRect];
}
참고로, 이것은 잘 작동하지만 셀을 편집 할 때 중앙에 머무르지는 않았지만 ... 때로는 텍스트가 많은 셀이있는 셀이 있으며이 코드가 텍스트 높이가 더 커지면 잘못 정렬 될 수 있습니다. 그런 다음 세포가 수직으로 중심을 두려고합니다. 여기에 수정 된 방법이 있습니다.
- (NSRect)titleRectForBounds:(NSRect)theRect
{
NSRect titleFrame = [super titleRectForBounds:theRect];
NSSize titleSize = [[self attributedStringValue] size];
// test to see if the text height is bigger then the cell, if it is,
// don't try to center it or it will be pushed up out of the cell!
if ( titleSize.height < theRect.size.height ) {
titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
}
return titleFrame;
}
Matt Ball을 사용하여 이것을 시도하는 사람에게 drawInteriorWithFrame:inView:
방법, 셀을 그리도록 설정 한 경우 더 이상 배경을 그립니다. 이것을 해결하기 위해 줄을 따라 무언가를 추가하십시오
[[NSColor lightGrayColor] set];
NSRectFill(cellFrame);
당신의 시작에 drawInteriorWithFrame:inView:
방법.
이것은 꽤 오래된 질문이지만 ...
NstableView 구현의 기본 스타일은 동일한 크기 및 글꼴의 단일 라인 텍스트 디스플레이를 위해 엄격하게 의도 된 것으로 생각합니다.
이 경우 추천합니다.
- 글꼴을 설정하십시오.
- 조정하다
rowHeight
.
어쩌면 당신은 조용히 울창한 행을 얻을 것입니다. 그런 다음 설정하여 패딩을 제공하십시오 intercellSpacing
.
예를 들어,
core_table_view.rowHeight = [NSFont systemFontSizeForControlSize:(NSSmallControlSize)] + 4;
core_table_view.intercellSpacing = CGSizeMake(10, 80);
여기에서 두 가지 속성 조정으로 얻을 수 있습니다.
이것은 멀티 라인 텍스트에는 효과가 없지만 멀티 라인 지원이 필요하지 않은 경우 빠른 수직 센터에 충분히 좋습니다.
나는 같은 문제가 있었고 여기에 내가 한 해결책이 있습니다.
1) 인터페이스 빌더에서 NSTABLECELLVIEW를 선택하십시오. 크기 검사관의 행 높이만큼 큰지 확인하십시오. 예를 들어, 행 높이가 32 인 경우 셀 높이 32를 만드십시오.
2) 당신의 셀이 당신의 줄에 잘 배치되어 있는지 확인하십시오 (나는 가시적입니다)
3) 셀 내부의 텍스트 필드를 선택하고 크기 검사관으로 이동하십시오.
4) "정렬"항목을보고 "컨테이너의 수직 중앙"을 선택해야합니다.
-> 텍스트 필드가 셀에 중심을 둔다.
아니요. 올바른 방법은 필드를 다른보기에 놓고 자동 레이아웃 또는 부모보기 레이아웃을 사용하여 위치를 배치하는 것입니다.