【问题标题】:Displaying a Cocoa Window as a Sheet in Xcode 4 (OSX 10.7.2) with ARC使用 ARC 在 Xcode 4 (OSX 10.7.2) 中将 Cocoa 窗口显示为工作表
【发布时间】:2011-12-24 21:52:18
【问题描述】:

我正在尝试从我的 MainWindow 中将登录窗口显示为工作表,但是每当我尝试实现 AppKit 方法时,由于各种无法区分的原因总是会弹出错误。

那里的在线指南都不起作用,当我将他们的代码/改编的类应用于我自己的项目时,它们永远不会起作用。

大部分指南都已严重过时,包括 Apple 文档。而且它们似乎都不与自动引用计数兼容。或者 Xcode 4 接口。

有人可以为我详细介绍一份完整的指南,了解在主窗口上按下按钮后显示工作表的最简单方法。

如果需要,请随时询问更多信息。

【问题讨论】:

    标签: cocoa osx-lion xcode4.2 automatic-ref-counting cocoa-sheet


    【解决方案1】:

    Xcode 4 教程

    创建新项目并将以下内容添加到AppDelegate.hAppDelegate.m

    AppDelegate.h

    #import <Cocoa/Cocoa.h>
    
    @interface AppDelegate : NSObject <NSApplicationDelegate> {
    
        IBOutlet NSPanel *theSheet;
    }
    
    @property (assign) IBOutlet NSWindow *window;
    
    @end
    

    AppDelegate.m

    #import "AppDelegate.h"
    
    @implementation AppDelegate
    
    @synthesize window = _window;
    
    - (IBAction) showTheSheet:(id)sender {
    
        [NSApp beginSheet:theSheet
           modalForWindow:(NSWindow *)_window
            modalDelegate:self
           didEndSelector:nil
              contextInfo:nil];
    
    }
    
    -(IBAction)endTheSheet:(id)sender {
    
        [NSApp endSheet:theSheet];
        [theSheet orderOut:sender];
    
    }
    
    @end
    

    打开MainMenu.xib
    使用现有的NSWindow
    使用以下按钮使其可见:

    创建一个新的NSPanel
    添加相应的NSButtons

    Close 连接到App Delegate

    然后选择endTheSheet

    Open 连接到App Delegate

    然后选择showTheSheet

    App Delegate 连接到新的NSPanel

    然后选择theSheet

    选择NSPanel 并禁用Visible At Launch(基本步骤!)

    现在点击运行并享受结果:

    【讨论】:

    • 你的翻转太棒了!这些截图真的很好,很有帮助,非常感谢。
    • 就上述示例向 Anne 提出问题:如果我要在工作表中添加一个 NSTextField,如何在工作表及其父窗口之间来回传输文本?
    • @Woofy,您找到解决方案了吗?谢谢
    • 你的屏幕截图让我想起了绝地大师的工作。谢谢:)
    • 今天你是我的英雄!非常感谢:D
    【解决方案2】:

    SDK 10.10 中的情况发生了变化——我认为这些调用更容易理解。父窗口负责将子 NSWindow 作为工作表启动 - 然后将此子 NSWindow 传递给 NSApp 以模态方式运行。然后反其道而行之。

    显示工作表

    显示工作表而不是调用:

    [NSApp beginSheet:theSheet
       modalForWindow:(NSWindow *)_window
        modalDelegate:self
       didEndSelector:nil
          contextInfo:nil];
    

    你现在调用父窗口:

    (void)beginSheet:(NSWindow *)sheetWindow
     completionHandler:(void (^)(NSModalResponse returnCode))handler
    

    然后要在模态循环中运行工作表,您还必须调用 NSApp:

    - (NSInteger)runModalForWindow:(NSWindow *)aWindow
    

    结束表

    要关闭工作表,请调用父窗口:

    - (void)endSheet:(NSWindow *)sheetWindow
    

    这会导致上述调用中的 completionHandler 触发, - 您可以在其中调用 NSApp 来停止运行模式窗口:

    - (void)stopModalWithCode:(NSInteger)returnCode
    

    完整示例

    @implementation AppDelegate
    
    @synthesize window = _window;
    
    - (IBAction) showTheSheet:(id)sender {
    
        [_window beginSheet: theSheet
             completionHandler:^(NSModalResponse returnCode) {
                 [NSApp stopModalWithCode: returnCode];
             }];
    
        [NSApp runModalForWindow: theSheet];
    
    }
    
    -(IBAction)endTheSheet:(id)sender {
        [_window endSheet: theSheet];
    }
    
    @end
    

    【讨论】:

    • 如果这不应该在这里(因为标题是特定于 xcode 4,请在投票前告诉我,我会删除它)
    • 需要说明的是,在调用beginSheet之前必须隐藏工作表窗口,否则看起来像工作表但没有附加。
    猜你喜欢
    • 2010-12-29
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    相关资源
    最近更新 更多