如果您要求強制窗口使用比Cocoa更低級別的API重新繪製自己的窗口,那麼據我所知,這是不可能的。一個窗口在其內容視圖的drawRect:方法被調用時重繪自己。它將一個CGContextRef傳遞給窗口,然後該窗口使用該窗口重新繪製窗口。 CoreGraphics不負責重新繪製窗口。可可使用CoreGraphics重繪窗口。
它有可能獲得一個窗口的graphicscontext的drawRect之外:(見,例如,here),然後繪製到,只要你想, 但它聽起來像是你真的想要做的是攔截結果這個窗口的普通繪圖程序,並在頂部做一些你自己的東西。您可以通過切換窗口內容視圖的類並重寫drawRect來完成此操作。一個輔助函數來處理注入將是這個樣子:
typedef void (^InjectedBlock)(CGContextRef, CGRect);
void InjectIntoView(NSView* view, InjectedBlock aBlock)
{
Class viewClass = [view class];
InjectedBlock injectedBlock = [aBlock copy];
void(^drawRect)(id, SEL, NSRect) = ^(id self, SEL _cmd, NSRect rect)
{
struct objc_super superId = { self, viewClass };
objc_msgSendSuper(superId, @selector(drawRect:), rect);
injectedBlock([[NSGraphicsContext currentContext] graphicsPort], CGRectFromNSRect(rect));
};
NSString* subclassName = [NSString stringWithFormat:"%s_injected", class_getName(viewClass)]
Class subclass objc_allocateClassPair(viewClass, [subclassName UTF8String], 0);
objc_registerClassPair(subclass);
Method overriddenMethod = class_getInstanceMethod([NSView class], @selector(drawRect:));
IMP imp = imp_implementationWithBlock(drawRect);
class_addMethod(subclass, @selector(drawRect:), imp, method_getTypeEncoding(overriddenMethod))
}
編輯:
唉唉,你感興趣的整個窗口。框架等也是NSView實例,但它們是您無法直接訪問的NSView的私有子類。您可以通過在窗口上調用display
來強制重繪它們,但這可能會覆蓋您對窗口所做的任何操作,因爲它將使用這些類的現有繪圖例程。
因此,您可能還需要考慮在drawRect中調用drawRect:這些視圖的方法(調用[[NSGraphicsContext currentContext] graphicsPort]:將爲您提供可用於Quartz API的CGContextRef)。您可以通過在窗口的內容視圖中調用superview
來獲取框架視圖。
請注意,窗口框架視圖的排列沒有記錄,並可能隨系統更新而改變。
聽起來像一個有趣的項目,反正!
有沒有像Mac上的invalidateRect這迫使窗口重繪? – MacGeek