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