自定义NSTextFieldCell时遇到的问题

发布于 2024-08-20 00:30:47 字数 6111 浏览 5 评论 0原文

我正在尝试在大纲视图中创建单元格,就像我们在 Skype 消息窗口中为用户所做的那样。

  1. 为此,我创建了一个自定义类:

IconNameCell.h

    @interface IconNameCell : NSTextFieldCell {
        //@private
        NSImage *userImage;  // size (17,17)
        NSImage *statusIcon; // size (14,14)
        NSString *cellText;

    }
    @property (readwrite, retain) NSImage *userImage;
    @property (readwrite, retain) NSImage *statusIcon;
    @property (readwrite, retain) NSString *cellText;
    - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
    @end

IconNameCell.m

@implementation IconNameCell
@synthesize userImage;
@synthesize statusIcon;
@synthesize cellText;


- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{
    @try{
    // Inset the cell frame to give everything a little horizontal padding
    NSRect anInsetRect = NSInsetRect(cellFrame,2.0,0); 

    //FIXME: flip coordinates and size can be set in accessor methods
    // setting userImage and statusIcon in flipped coordinate 
    [userImage setFlipped:YES];
    [statusIcon setFlipped:YES];

    // setting size of image and icon
    [userImage setSize:NSMakeSize(25.0, 25.0)];
    [statusIcon setSize:NSMakeSize(15.0, 17.0)];

    // setting attributes of cell text
    NSMutableParagraphStyle *dParagraphStyle = [[NSMutableParagraphStyle alloc] init];
    [dParagraphStyle setAlignment:NSLeftTextAlignment];

    NSColor *colorOfText;
    if ([self isHighlighted]) {
        colorOfText = [NSColor whiteColor]; 
    }
    else {
        colorOfText = [NSColor blackColor];
    }

    NSMutableDictionary * dTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                               colorOfText,NSForegroundColorAttributeName,
                                               [NSFont systemFontOfSize:11.0],NSFontAttributeName,
                                               dParagraphStyle, NSParagraphStyleAttributeName,
                                               nil];

    // getting sizes
    NSSize cellTextSize = [cellText sizeWithAttributes:dTitleAttributes];
    NSSize userImageSize = [userImage size];
    NSSize statusIconSize = [statusIcon size];

    // making layout boxes for all elements

    // vertical padding between the lines of text
    float dVerticalPadding = 2.0;

    // horizontal padding between two images
    float padBtwnImgs = 4.0;

    // horizontal padding between image and text
    float padBtwnImgText = 6.0;


        NSString *userImageName = [userImage name];
        NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); // getting null for userImageName

        //if ([userImageName isEqualToString:@"current_D.png"]) {


        //FIXME: this is juggad and should be corrected 
        NSRange rangeOfComma = [cellText rangeOfString:@","];
        if (rangeOfComma.length !=0 ) {
            //<#statements#>

        // userImage box: center the userImage vertically inside of the inset rect
        NSRect cellTitleBox = NSMakeRect(anInsetRect.origin.x,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
                                         cellTextSize.width,
                                         cellTextSize.height);

        // drawing cell text
        [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
    }
    else {
        // userImage box: center the userImage vertically inside of the inset rect
        NSRect userImageBox = NSMakeRect(anInsetRect.origin.x,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - userImageSize.height*.5,
                                         userImageSize.width,
                                         userImageSize.height);

        // statusIcon box: center the statusIcon vertically inside of the inset rect
        NSRect statusIconBox = NSMakeRect(userImageBox.origin.x + userImageBox.size.width + padBtwnImgs,
                                          anInsetRect.origin.y + anInsetRect.size.height*.5 - statusIconSize.height*.5,
                                          statusIconSize.width,
                                          statusIconSize.height);

        // cellTitleBox: vertically aligning text
        NSRect cellTitleBox = NSMakeRect(statusIconBox.origin.x + statusIconBox.size.width + padBtwnImgText,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
                                         cellTextSize.width,
                                         cellTextSize.height);

        // drawing user image
        [userImage drawInRect:userImageBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

        // drawing user status
        [statusIcon drawInRect:statusIconBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

        // drawing cell text
        [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
    }
    }
    @catch (NSException *e) {
        NSLog(@"IconNameCell -%@",e);
    }


}
@end

第二,我为大纲视图分配了文本字段单元格:IB 中的 IconNameCell

第三,我在委托中使用此代码在自定义单元格中设置图像、图标和用户名称-

 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item{
        if ([[tableColumn identifier] isEqualToString:@"userInfo"]) {
          // some relevant code

          if( [[item onlineStatus] intValue] == 0 ){
        [cell setStatusIcon:[NSImage imageNamed:@"offline.png"]];
        }
        else{
        [cell setStatusIcon:[NSImage imageNamed:@"online.png"]];
        }

        //similarly, setting attribute for userImage and cellText

        } 

我面临两个问题: 1. 当我在大纲视图中选择一行或另一行时,应用程序经常崩溃。早些时候,当我没有采用自定义单元格,而是采用三个不同的列时 - 用户图像、用户状态和用户名,它工作正常! 2. 对于日志: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText);我得到 (null) 作为 userImageName,尽管我应该得到它的一些字符串值。

有人能给我建议一些解决方案吗?

谢谢,

米拉杰

I am trying to make cells in an outline view just like we have for users in Skype's message window.

  1. For this I created a custom class:

IconNameCell.h

    @interface IconNameCell : NSTextFieldCell {
        //@private
        NSImage *userImage;  // size (17,17)
        NSImage *statusIcon; // size (14,14)
        NSString *cellText;

    }
    @property (readwrite, retain) NSImage *userImage;
    @property (readwrite, retain) NSImage *statusIcon;
    @property (readwrite, retain) NSString *cellText;
    - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
    @end

IconNameCell.m

@implementation IconNameCell
@synthesize userImage;
@synthesize statusIcon;
@synthesize cellText;


- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{
    @try{
    // Inset the cell frame to give everything a little horizontal padding
    NSRect anInsetRect = NSInsetRect(cellFrame,2.0,0); 

    //FIXME: flip coordinates and size can be set in accessor methods
    // setting userImage and statusIcon in flipped coordinate 
    [userImage setFlipped:YES];
    [statusIcon setFlipped:YES];

    // setting size of image and icon
    [userImage setSize:NSMakeSize(25.0, 25.0)];
    [statusIcon setSize:NSMakeSize(15.0, 17.0)];

    // setting attributes of cell text
    NSMutableParagraphStyle *dParagraphStyle = [[NSMutableParagraphStyle alloc] init];
    [dParagraphStyle setAlignment:NSLeftTextAlignment];

    NSColor *colorOfText;
    if ([self isHighlighted]) {
        colorOfText = [NSColor whiteColor]; 
    }
    else {
        colorOfText = [NSColor blackColor];
    }

    NSMutableDictionary * dTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                               colorOfText,NSForegroundColorAttributeName,
                                               [NSFont systemFontOfSize:11.0],NSFontAttributeName,
                                               dParagraphStyle, NSParagraphStyleAttributeName,
                                               nil];

    // getting sizes
    NSSize cellTextSize = [cellText sizeWithAttributes:dTitleAttributes];
    NSSize userImageSize = [userImage size];
    NSSize statusIconSize = [statusIcon size];

    // making layout boxes for all elements

    // vertical padding between the lines of text
    float dVerticalPadding = 2.0;

    // horizontal padding between two images
    float padBtwnImgs = 4.0;

    // horizontal padding between image and text
    float padBtwnImgText = 6.0;


        NSString *userImageName = [userImage name];
        NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); // getting null for userImageName

        //if ([userImageName isEqualToString:@"current_D.png"]) {


        //FIXME: this is juggad and should be corrected 
        NSRange rangeOfComma = [cellText rangeOfString:@","];
        if (rangeOfComma.length !=0 ) {
            //<#statements#>

        // userImage box: center the userImage vertically inside of the inset rect
        NSRect cellTitleBox = NSMakeRect(anInsetRect.origin.x,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
                                         cellTextSize.width,
                                         cellTextSize.height);

        // drawing cell text
        [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
    }
    else {
        // userImage box: center the userImage vertically inside of the inset rect
        NSRect userImageBox = NSMakeRect(anInsetRect.origin.x,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - userImageSize.height*.5,
                                         userImageSize.width,
                                         userImageSize.height);

        // statusIcon box: center the statusIcon vertically inside of the inset rect
        NSRect statusIconBox = NSMakeRect(userImageBox.origin.x + userImageBox.size.width + padBtwnImgs,
                                          anInsetRect.origin.y + anInsetRect.size.height*.5 - statusIconSize.height*.5,
                                          statusIconSize.width,
                                          statusIconSize.height);

        // cellTitleBox: vertically aligning text
        NSRect cellTitleBox = NSMakeRect(statusIconBox.origin.x + statusIconBox.size.width + padBtwnImgText,
                                         anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
                                         cellTextSize.width,
                                         cellTextSize.height);

        // drawing user image
        [userImage drawInRect:userImageBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

        // drawing user status
        [statusIcon drawInRect:statusIconBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

        // drawing cell text
        [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
    }
    }
    @catch (NSException *e) {
        NSLog(@"IconNameCell -%@",e);
    }


}
@end

2nd, I assigned text field cell for outline view the class: IconNameCell in IB

3rd, I used this code in delegate to set image, icon and name of user in custom cell-

 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item{
        if ([[tableColumn identifier] isEqualToString:@"userInfo"]) {
          // some relevant code

          if( [[item onlineStatus] intValue] == 0 ){
        [cell setStatusIcon:[NSImage imageNamed:@"offline.png"]];
        }
        else{
        [cell setStatusIcon:[NSImage imageNamed:@"online.png"]];
        }

        //similarly, setting attribute for userImage and cellText

        } 

I am facing two problems with it: 1. Application is frequently crashing when I am selecting one or the other row in outline view. Earlier when I had not taken the customized cell but three different columns for - user image, user status and user name it was working fine! 2. For the log: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); I am getting (null) as userImageName, although I should get some string value for it.

Can anyone suggest me some solution for it??

Thanks,

Miraaj

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽清梦 2024-08-27 00:30:47
  1. 当我在大纲视图中选择一行或另一行时,应用程序经常崩溃。

请编辑您的问题以包含崩溃日志。

2.对于日志: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText);我得到 (null) 作为 userImageName,尽管我应该得到它的一些字符串值。

您是否使用 setName: 设置图像名称或从 imageNamed: 获取图像名称?否则,它就没有,并且此输出是正确的。

  1. Application is frequently crashing when I am selecting one or the other row in outline view.

Please edit your question to include the crash log.

2. For the log: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); I am getting (null) as userImageName, although I should get some string value for it.

Have you set the image's name with setName: or obtained it from imageNamed:? Otherwise, it doesn't have one, and this output is correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文