【问题标题】:Sheets are not displaying properly on OSX工作表无法在 OSX 上正确显示
【发布时间】:2012-10-10 21:36:44
【问题描述】:

我对 OSX 开发非常陌生。将此视为我的第一个应用程序。我想在主窗口上单击按钮时显示一张工作表。我正在使用笔尖

以下是我的 .h 文件代码

#import <Foundation/Foundation.h>
#import "WebKit/Webkit.h"

@interface MainViewObject : NSObject
- (IBAction)accountButtonPressed:(id)sender;
- (IBAction)cancelSheetButtonPressed:(id)sender;

.m文件如下

#import "MainViewObject.h"
@implementation MainViewObject

- (IBAction)accountButtonPressed:(id)sender {
    [NSApp beginSheet:self.accountSheet
   modalForWindow:[mainWindowView window]
    modalDelegate:nil
   didEndSelector:nil
      contextInfo:nil];

[NSApp runModalForWindow:self.accountSheet];

[NSApp endSheet:self.accountSheet];
[self.accountSheet orderOut:self];
}

- (IBAction)cancelSheetButtonPressed:(id)sender {
// Return to normal event handling
[NSApp endSheet:self.accountSheet];
// Hide the sheet
[self.accountSheet orderOut:sender];
}

当我运行应用程序时,我会得到如下信息:

http://i.imgur.com/DzJJ6.png

我被困住了,我不知道这有什么问题。我无法获得工作表,甚至无法关闭应用程序。我参考了网上的一些例子。

【问题讨论】:

    标签: macos window cocoa-sheet


    【解决方案1】:
    - (IBAction)accountButtonPressed:(id)sender {
        [NSApp beginSheet:self.accountSheet
       modalForWindow:[mainWindowView window]
        modalDelegate:nil
       didEndSelector:nil
          contextInfo:nil];
    
        [NSApp runModalForWindow:self.accountSheet];
    
        [NSApp endSheet:self.accountSheet];
        [self.accountSheet orderOut:self];
    
    }
    

    哇,看看这个,截图看起来就是这样也就不足为奇了。

    让我们一次走过那一行。当您点击“帐户”按钮时,您会立即连续执行 4 件事:

    1. 您正在告诉应用程序开始显示附加到您的主窗口的工作表。这没关系,实际上是您在 accountButtonPressed: 方法中需要的唯一代码。

    2. 在开始该工作表之后,您告诉应用程序您还希望以应用程序模式的方式单独显示该工作表(不附加到任何窗口,而是在屏幕中间),这阻止在应用程序中处理所有其他事件。换句话说,这条线并没有真正的意义。您可以以“文档模式”方式(仅绑定该工作表所附加到的窗口)或以“应用程序模式”方式将窗口显示为工作表,但不能同时显示两者。 ;-)

    3. 在刚刚显示工作表后,您立即告诉NSApp 停止显示工作表。现在,您确实希望最终执行此操作,但在刚刚显示的 0.0005 秒后关闭工作表可能会让您的用户有些沮丧。

    4. 您现在告诉工作表隐藏自己。这需要通过您的 didEndSelector: 方法完成,这将我们带到您的第一个方法中的问题。

    -

    [NSApp beginSheet:self.accountSheet
       modalForWindow:[mainWindowView window]
        modalDelegate:nil
       didEndSelector:nil
          contextInfo:nil];
    

    这很好,但请阅读 beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:Sheet Programming Topics: Using Custom Sheets 的文档。 (Class Reference 页面顶部的 Companion 指南链接对于学习如何在现实世界中使用 API 特别有帮助。它们在我学习时非常有帮助。

    modalDelegate: 指定nil 意味着您没有任何等待通知工作表何时停止显示的信息(当您调用[NSApp endSheet:sheet] 时会发生这种情况)。您还没有指定要在工作表结束时调用的@selector。选择器有点像函数,也就是“方法”。

    您的代码应如下所示:

    @implementation MDAppDelegate
    
    - (IBAction)showSheet:(id)sender {
        [NSApp beginSheet:self.sheet
           modalForWindow:self.window
            modalDelegate:self
           didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
              contextInfo:NULL];
    }
    
    - (IBAction)cancel:(id)sender {
        [NSApp endSheet:self.sheet];
    }
    
    - (IBAction)ok:(id)sender {
        [NSApp endSheet:self.sheet];
    }
    
    - (void)sheetDidEnd:(NSWindow *)sheet
                returnCode:(NSInteger)returnCode
                   contextInfo:(void *)contextInfo {
        [sheet orderOut:nil];
    }
    @end
    

    在此示例中,您单击“显示工作表”按钮,工作表开始显示为附加到主窗口。在工作表中,有一个“取消”和一个“确定”按钮,它们都调用了各自的方法。在每种方法中,您都调用[NSApp endSheet:self.sheet]。这告诉NSApp 它应该在指定为模态委托的对象上调用sheetDidEnd:returnCode:contextInfo: 方法。然后在sheetDidEnd:returnCode:contextInfo: 中告诉工作表隐藏自己。

    编辑:

    每个NSWindow 都有一个“启动时可见”标志,可以在 Interface Builder 中设置。如果设置了此标志,则在加载 nib 文件时窗口将可见。如果未设置,则窗口将隐藏,直到您以编程方式显示它。只需编辑 nib 文件中的标志,如下所示:

    【讨论】:

    • 我最后用了你给的代码。当我运行应用程序时,我看到两个窗口都显示在单击按钮获取工作表之前。这是同一i.imgur.com/XWNSk.png的快照
    • 关于如何最初隐藏工作表窗口的任何想法,因为我看到如果我关闭默认打开的工作表(如前面的评论链接所示)并按下按钮它工作正常
    • 答案确实很好,但作者得到的大多数批评都是徒劳的。原帖中的代码与Apple's documentation here 中的代码完全相同。事实上,从1到4的所有“错误”都与现实无关。 @Raj 唯一错过的是 Visible At Launch 复选框,需要取消选中。
    • 我遇到了完全相同的问题,启动时可见复选框就是解决方案,i4niac,也许您想直接回答这个解决方案的问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多