2013-02-25 24 views
5

Tôi đã triển khai hoàn tác/làm lại cách tiêu chuẩn (NSUndoManager) nhưng không thể tìm hiểu cách tôi vô hiệu hóa hoàn tác/làm lại khi ứng dụng của tôi ở trạng thái cụ thể.Tắt hoàn tác/làm lại trong ứng dụng Cocoa

Người dùng vẽ mọi thứ trong ứng dụng của tôi và khi những gì họ đã vẽ đang tải lên, tôi vô hiệu hóa giao diện người dùng và tất nhiên không muốn người dùng có thể hoàn tác/làm lại.

Tôi sử dụng Trình quản lý hoàn tác của NSView vì vậy tôi đoán một cách có thể là chỉ làm cho chế độ xem đó từ chức phản hồi đầu tiên. Có cách nào khác không?

Trả lời

1

Bạn có thể hoàn thiện Undo và Redo với

- (void) removeAllActions; 

hoặc loại bỏ các hành động cho một mục tiêu cụ thể với

- (void) removeAllActionsWithTarget: (id) target; 

Nếu bạn chỉ đơn giản là muốn vô hiệu hóa bất cứ hành động trong một thời gian, để lại lùi lại chồng không thay đổi, chỉ cần vô hiệu hóa t anh Undo/Redo các mục menu sử dụng NSMenuValidationProtocol của

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem; 
+0

Đúng. Điều đó đã làm điều đó. Đã phải thực hiện (IBAction) undo: (id) người gửi mặc dù. – Sebastian

-1

Cách tiếp cận tốt nhất tôi có thể nghĩ là làm cho phương thức -undoManager của chế độ xem trở lại trong khi tải lên, sẽ xóa nó khỏi chuỗi trả lời và khiến các tùy chọn hoàn tác/làm lại bị tắt cho chế độ xem đó.

(Tôi đã không kiểm tra này, nhưng tôi 99% chắc chắn rằng các menu sẽ hỏi xem bạn cho người quản lý undo bất cứ khi nào nó xác nhận các tùy chọn menu.)

2

Nếu xem là trả lời đầu tiên, bạn có thể thực hiện các giao thức validateMenuItem: để vô hiệu hóa hoặc kích hoạt các mục menu theo tình trạng hiện tại của bạn.

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem { 
    SEL action = menuItem.action; 

    if (action == @selector(undo:) || 
     action == @selector(redo:)) { 
      return !uploadingImage; 
    } 
    return YES; 
} 
-1

Tài liệu là bạn của bạn. Phương thức disableUndoRegistration của NSUndoManager có "vô hiệu hóa" trong tên của nó. Tùy thuộc vào bộ điều khiển của ứng dụng để quyết định thời điểm thích hợp để tắt và bật lại đăng ký hoàn tác.

+0

Đó là về cài đặt của các sự kiện hoàn tác, không phải là vô hiệu hóa các menu hoàn tác/làm lại. – martinjbaker

0

Tôi đã có tình huống tương tự khi tôi muốn vô hiệu hóa một số điều kiện hoàn tác/làm lại khi ứng dụng ở trạng thái cụ thể (trong khi vẫn cho phép hoàn tác/làm lại cho các hoạt động khác).

Phương pháp triển khai - (BOOL)validateMenuItem:(NSMenuItem *)item trên chế độ xem không hoạt động đối với tôi (Tôi có ứng dụng dựa trên tài liệu vào ngày 10.12). Theo các tài liệu tại https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html:

Nếu có một đối tượng trong chuỗi trả lời khi mà thực hiện hành động của mục, NSMenu sau đó kiểm tra xem đối tượng mà thực hiện các validateMenuItem: hoặc validateUserInterfaceItem: phương pháp. Nếu không, thì mục menu được bật. Nếu có, thì trạng thái được bật của mục menu được xác định bởi giá trị trả về của phương thức.

Chế độ xem sẽ phải thêm phương thức hoàn tác cũng làm điều đúng.

Khi tôi thăm dò chuỗi trả lời, tôi thấy rằng NSWindow tôi là đối tượng mà đáp lại undo: (mặc dù nó không phải là một phần của giao diện tài liệu), do đó kế hoạch hiện tại của tôi là sử dụng một tùy chỉnh NSWindow lớp con với imeplementation của validateMenuItem , dọc theo dòng:

#import "Window.h" 

@implementation SBXWindow 

- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen 
{ 
    self = [super initWithContentRect:contentRect styleMask:style backing:bufferingType defer:flag screen:screen]; 

    return self; 
} 


- (BOOL)validateMenuItem:(NSMenuItem *)item 
{ 
    // Call super imeplementation as it appears to update the menu item title (and potentially other stuff) 
    BOOL result = [super validateMenuItem:item]; 
    if (result == NO) { 
     return NO; 
    } 

    if (item.action == @selector(undo:) || item.action == @selector(redo:)) { 
     // Add custom logic here 
    } 

    return result; 
} 

@end 

Tuy nhiên có cảnh báo rằng undo:redo: phương pháp này không thực hiện. Đây có thể được loại bỏ bằng cách tạo ra một thể loại trên NSWindow, chẳng hạn như:

@interface NSWindow (SBXUndoable) 

- (void)undo:(id)sender; 
- (void)redo:(id)sender; 

@end 

Không chắc nếu có bất kỳ vấn đề với việc đó (tôi không nhận thấy bất kỳ), nhưng nó loại bỏ các cảnh báo. Tôi đã thay đổi lớp học thành một lớp học Swift, mà không có bất kỳ cảnh báo nào để giải quyết.

Các vấn đề liên quan