title&&close button not show - macos

I try to show/hide the title bar in a cocoa app. I use following code :
if ([window styleMask]==NSResizableWindowMask) {
[window setStyleMask:NSMiniaturizableWindowMask|NSClosableWindowMask|NSResizableWindowMask|NSTitledWindowMask];
}else{
[window setStyleMask:NSResizableWindowMask];
}
It works well before 10.10 but fails in 10.10. In 10.10, when the title bar is shown, the title, close/minimize/resize buttons are unshown. Only user resizes the window, those things will be shown.
I guess that something needs to be 'Flush' and hence I also try to add:
[window update];
[window display];
[[NSApplication sharedApplication] setWindowsNeedUpdate:YES];
[[NSApplication sharedApplication] updateWindows];
But all is failed.
Could anyone give any suggestion? Thanks!

This is an interesting issue. Can you file a bug report with Apple?
In the meantime, here is a hack that seems to fix the issue:
if ([window styleMask] == NSResizableWindowMask) {
NSDisableScreenUpdates();
[window setStyleMask:(NSMiniaturizableWindowMask|NSClosableWindowMask
|NSResizableWindowMask|NSTitledWindowMask)];
NSRect frame = [window frame];
frame.size.width += 1;
[window setFrame:frame display:NO];
frame.size.width -= 1;
[window setFrame:frame display:YES];
NSEnableScreenUpdates();
} else {
[window setStyleMask:NSResizableWindowMask];
}
(In addition, it seems that you will have to manually restore the title with setTitle:.)

Use
dispatch_async(dispatch_get_main_queue(), ^{
if ([window styleMask]==NSResizableWindowMask)
{
[window setStyleMask:NSMiniaturizableWindowMask|NSClosableWindowMask|NSResizableWindowMask|NSTitledWindowMask];
}
else
{
[window setStyleMask:NSResizableWindowMask];
}
});
it works in my case.

Related

Label/Text in Xcode Appears Blurry

I am trying to make a preferences view with lots of text. I cannot figure out why the text is blurry when i run the project, even though the interface builder is very sharp and clear. Here is a picture. [1]: http://i.stack.imgur.com/EQl6D.png
here is the code for the views:
#implementation SKMainWindowController
-(NSRect)newFrameForNewContentView:(NSView*)view {
NSWindow *window = [self window];
NSRect newFrameRect = [window frameRectForContentRect:[view frame]];
NSRect oldFrameRect = [window frame];
NSSize newSize = newFrameRect.size;
NSSize oldSize = oldFrameRect.size;
NSRect frame = [window frame];
frame.size = newSize;
frame.origin.y -= (newSize.height - oldSize.height);
return frame;
}
-(NSView *)viewForTag:(int)tag {
NSView *view = nil;
switch (tag) {
case 0: default:
view = welcome;
break;
case 1:
view = status;
break;
case 2:
view = power;
break;
case 3:
view = preferences;
break;
case 4:
view = about;
break;
}
return view;
}
- (BOOL)validateToolbarItem:(NSToolbarItem *)item {
if ([item tag] == currentViewTag) return NO;
else return YES;
}
-(void)awakeFromNib {
[[self window] setContentSize:[welcome frame].size];
[[[self window] contentView] addSubview:welcome];
[[[self window] contentView] setWantsLayer:NO];
}
-(IBAction)switchWelcome:(id)sender {
int tag = [sender tag];
NSView *view = [self viewForTag:tag];
NSView *previousView = [self viewForTag:currentViewTag];
currentViewTag = tag;
NSRect newFrame = [self newFrameForNewContentView:view];
[NSAnimationContext beginGrouping];
if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask)
[[NSAnimationContext currentContext] setDuration:1.0];
[[[[self window] contentView] animator] replaceSubview:previousView with:view];
[[[self window] animator] setFrame:newFrame display:YES];
[NSAnimationContext endGrouping];
[welcomeButton setState:NSOnState];
[statsButton setState:NSOffState];
[powerButton setState:NSOffState];
}
I've tried changing the text fields into code by doing things like [textField setStringValue:#""];, but with no luck it is still blurry. Thanks for any help. PS: This is for cocoa, not iOS.
Found the answer, ended up being the stupid visual effect view not cooperating. Simple fix was to set the visual effect view to within the window, and set as inactive. (although there is now no point in having a visual effect view.)

Full Screen Cocoa Application - Force Quit

I am facing a weird issue when trying to make a full screen application. I am currently using a a NSWindow with a NSBorderlessWindowMask to make the screen show at top, and I subclassed NSWindow to accept keys:
- (BOOL) canBecomeKeyWindow
{
return YES;
}
This works fine, and I can use keys in my window, and quit out of the application with Command + Q. However, when I try to force quit the application on my Mac, the screen freezes, and I must restart my computer. I have a simple WebView inside my Window:
mainWindow = [[MyBorderWindow alloc] initWithContentRect:screenRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO screen:[NSScreen mainScreen]];
[mainWindow setLevel:windowLevel];
[mainWindow setBackgroundColor:[NSColor blackColor]];
[mainWindow makeKeyAndOrderFront:nil];
NSView *contentView = [mainWindow contentView];
WebView *customView = [[WebView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];
[contentView addSubview:customView];
I have tried the application on another computer, and force quit does not freeze the screen. Both computers are running OS X Mavericks.
Please let me know if there is anything else I should add.
Thanks in advance,
Bucco
Edit:
I think that my applicationWillTerminate method in AppDelegate might be part of the issue, but am not sure. Why would this method work fine on another computer, but not mine?
- (void)applicationWillTerminate:(NSNotification *)notification
{
[mainWindow orderOut:self];
// Release the display(s)
if (CGDisplayRelease( kCGDirectMainDisplay ) != kCGErrorSuccess) {
NSLog( #"Couldn't release the display(s)!" );
}
}

Prevent autoloading of last opened document

Currently, the default behavior of a Cocoa NSDocument based app is for it to open the last document that was opened automatically. How can I prevent this from happening so I can provide my own behavior?
I did this by adding this method to my NSDocument subclass:
- (void)addWindowController:(NSWindowController *)aController {
//
// Overwritten to reset all window restoration, we do our own.
//
NSWindow *window=[aController window];
if(
[window respondsToSelector:#selector(setRestorationClass:)]
&& [window respondsToSelector:#selector(setRestorable:)]
&& [window respondsToSelector:#selector(invalidateRestorableState)]
)
{
[window setRestorationClass:Nil];
[window setRestorable:NO];
[window invalidateRestorableState];
}
[super addWindowController:aController];
}
IIRC that was all.

xcode iOS6 orientation landscape

I see a lot of questions about this subject but am unable to find a solution to the problem I am experiencing. I have created an iPad app that should be Landscape only - it works fine when ran on any os prior to iOS6 but on iOS6 the app opens in portrait view. This screenshot shows what I mean (sorry not a great explanation) http://s1342.beta.photobucket.com/user/designedbyria/media/ScreenShot2012-11-02at122113.png.html
I'm guessing the problem is somewhere in the below code, but I can't be sure. I have set the supported Interface Orientations to Landscape Left and Landscape Right only - but this has not worked. I have also taken a look at the questions here with no luck..
I am using xcode and cordova/phonegap
Interface orientation in iOS 6.0
Set orientation to landscape mode in xcode 4.5 GM IOS 6
iOS 6 apps - how to deal with iPhone 5 screen size?
Thanks in Advance!
/**
* This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up)
/
- (BOOL) application:(UIApplication)application didFinishLaunchingWithOptions: (NSDictionary*)launchOptions {
NSURL* url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
NSString* invokeString = nil;
if (url && [url isKindOfClass:[NSURL class]]) {
invokeString = [url absoluteString]; NSLog(#"iwill launchOptions = %#", url);
}
CGRect screenBounds = [[UIScreen mainScreen] bounds];
self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
self.window.autoresizesSubviews = YES;
CGRect viewBounds = [[UIScreen mainScreen] applicationFrame];
self.viewController = [[[MainViewController alloc] init] autorelease];
self.viewController.useSplashScreen = YES;
self.viewController.wwwFolderName = #"www";
self.viewController.startPage = #"index.html";
self.viewController.invokeString = invokeString;
self.viewController.view.frame = viewBounds;
// check whether the current orientation is supported: if it is, keep it, rather than forcing a rotation
BOOL forceStartupRotation = YES;
UIDeviceOrientation curDevOrientation = [[UIDevice currentDevice] orientation];
if (UIDeviceOrientationUnknown == UIInterfaceOrientationLandscapeLeft) {
// UIDevice isn't firing orientation notifications yet… go look at the status bar
curDevOrientation = (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation];
}
if (UIDeviceOrientationIsValidInterfaceOrientation(curDevOrientation)) {
for (NSNumber *orient in self.viewController.supportedOrientations) {
if ([orient intValue] == curDevOrientation) {
forceStartupRotation = YES;
break;
}
}
}
if (forceStartupRotation) {
NSLog(#"supportedOrientations: %#", self.viewController.supportedOrientations);
// The first item in the supportedOrientations array is the start orientation (guaranteed to be at least Portrait)
UIInterfaceOrientation newOrient = [[self.viewController.supportedOrientations objectAtIndex:0]
intValue];
NSLog(#"AppDelegate forcing status bar to: %d from: %d", newOrient, curDevOrientation);
[[UIApplication sharedApplication] setStatusBarOrientation:newOrient];
}
[self.window addSubview:self.viewController.view];
[self.window makeKeyAndVisible];
return YES; }
I had the same problem (but not using cordova/phonegap).
You have to set your view controller as a RootViewController in your appDelegate instead of just adding as a subview.
Replace in you appdelegate:
[self.window addSubview:self.viewController.view];
[self.window makeKeyAndVisible];
By
[self.window setRootViewController:self.viewController];
[self.window makeKeyAndVisible];
You can use the delegate
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
Using this delegate and the application will be present in Landscape mode or any desired orientation mode.
Try it.

Changing NSApplicationIcon across a running application?

I'd like to adjust the NSApplicationIcon image that gets shown automatically in all alerts to be something different than what is in the app bundle.
I know that it's possible to set the dock icon with [NSApplication setApplicationIconImage:] -- but this only affects the dock, and nothing else.
I'm able to work around this issue some of the time: I have an NSAlert *, I can call setIcon: to display my alternate image.
Unfortunately, I have a lot of nibs that have NSImageView's with NSApplicationIcon, that I would like to affect, and it would be a hassle to create outlets and put in code to change the icon. And for any alerts that I'm bringing up with the BeginAlert... type calls (which don't give an NSAlert object to muck with), I'm completely out of luck.
Can anybody think of a reasonable way to globally (for the life of a running application) override the NSApplicationIcon that is used by AppKit, with my own image, so that I can get 100% of the alerts replaced (and make my code simpler)?
Swizzle the [NSImage imageNamed:] method? This method works at least on Snow Leopard, YMMV.
In an NSImage category:
#implementation NSImage (Magic)
+ (void)load {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// have to call imageNamed: once prior to swizzling to avoid infinite loop
[[NSApplication sharedApplication] applicationIconImage];
// swizzle!
NSError *error = nil;
if (![NSImage jr_swizzleClassMethod:#selector(imageNamed:) withClassMethod:#selector(_sensible_imageNamed:) error:&error])
NSLog(#"couldn't swizzle imageNamed: application icons will not update: %#", error);
[pool release];
}
+ (id)_sensible_imageNamed:(NSString *)name {
if ([name isEqualToString:#"NSApplicationIcon"])
return [[NSApplication sharedApplication] applicationIconImage];
return [self _sensible_imageNamed:name];
}
#end
With this hacked up (untested, just wrote it) jr_swizzleClassMethod:... implementation:
+ (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_ {
#if OBJC_API_VERSION >= 2
Method origMethod = class_getClassMethod(self, origSel_);
if (!origMethod) {
SetNSError(error_, #"original method %# not found for class %#", NSStringFromSelector(origSel_), [self className]);
return NO;
}
Method altMethod = class_getClassMethod(self, altSel_);
if (!altMethod) {
SetNSError(error_, #"alternate method %# not found for class %#", NSStringFromSelector(altSel_), [self className]);
return NO;
}
id metaClass = objc_getMetaClass(class_getName(self));
class_addMethod(metaClass,
origSel_,
class_getMethodImplementation(metaClass, origSel_),
method_getTypeEncoding(origMethod));
class_addMethod(metaClass,
altSel_,
class_getMethodImplementation(metaClass, altSel_),
method_getTypeEncoding(altMethod));
method_exchangeImplementations(class_getClassMethod(self, origSel_), class_getClassMethod(self, altSel_));
return YES;
#else
assert(0);
return NO;
#endif
}
Then, this method to illustrate the point:
- (void)doMagic:(id)sender {
static int i = 0;
i = (i+1) % 2;
if (i)
[[NSApplication sharedApplication] setApplicationIconImage:[NSImage imageNamed:NSImageNameBonjour]];
else
[[NSApplication sharedApplication] setApplicationIconImage:[NSImage imageNamed:NSImageNameDotMac]];
// any pre-populated image views have to be set to nil first, otherwise their icon won't change
// [imageView setImage:nil];
// [imageView setImage:[NSImage imageNamed:NSImageNameApplicationIcon]];
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:#"Shazam!"];
[alert runModal];
}
A couple of caveats:
Any image view already created must have setImage: called twice, as seen above to register the image changing. Don't know why.
There may be a better way to force the initial imageNamed: call with #"NSApplicationIcon" than how I've done it.
Try [myImage setName:#"NSApplicationIcon"] (after setting it as the application icon image in NSApp).
Note: On 10.6 and later, you can and should use NSImageNameApplicationIcon instead of the string literal #"NSApplicationIcon".

Resources