I'm creating a new window and view programmatically. I need the view to accept First Responder status. For whatever reason it's not.
I'm doing this old school because I want my app to be compatible with older versions of OSX. Here's what I've got:
- (IBAction)startShow:(id)sender {
// Capture the main display
if (CGDisplayCapture( kCGDirectMainDisplay ) != kCGErrorSuccess) {
NSLog( #"Couldn't capture the main display!" );
}
// Get the shielding window level
windowLevel = CGShieldingWindowLevel();
// Get the screen rect of our main display
screenRect = [[NSScreen mainScreen] frame];
// Put up a new window
displayWindow = [[ShowWindow alloc] initWithContentRect:screenRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO screen:[NSScreen mainScreen]];
[displayWindow setBackgroundColor:[NSColor blackColor]];
[displayWindow setLevel:windowLevel];
[displayWindow makeKeyAndOrderFront:nil];
// Load show window with options from settings window.
[displayWindow loadOptions:screenRect];
}
Just to clarify, displayWindow is an instance of ShowWindow, which is a subclass of NSWindow. In my ShowWindow class I'm doing the following:
- (BOOL)canBecomeKeyWindow
{
return YES;
}
- (void) loadOptions:(NSRect)screenRect {
// Create custom view to hold text fields
view = [[ShowView alloc] initWithFrame: screenRect];
[self setContentView:view];
// Track Title Text Field Initialize
textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, screenRect.size.height / 4, screenRect.size.width, 350)];
[textField setStringValue:#"My Label"];
[textField setBezeled:NO];
[textField setDrawsBackground:NO];
[textField setEditable:NO];
[textField setSelectable:NO];
[textField setTextColor:[NSColor whiteColor]];
[textField setFont:[NSFont fontWithName:#"Helvetica" size:92]];
[textField setAlignment:NSCenterTextAlignment];
// Add track title text field to main view.
[view addSubview:textField];
// Make the view first responder
[self makeFirstResponder:view];
}
view is an instance of ShowView, which is a subclass of NSView. Last but not least here's what I've got going on in ShowView:
// Next four methods set main view as first responder to accept keyboard input
- (BOOL)acceptsFirstResponder
{
NSLog(#"I accepted being a first responder! Yea!");
return YES;
}
- (BOOL)resignFirstResponder
{
[self setNeedsDisplay:YES];
return YES;
}
- (BOOL)becomeFirstResponder
{
[self setNeedsDisplay:YES];
return YES;
}
- (void)insertText:(NSString *)input
{
}
Related
I created a custom object (NSImageView) to display images and I use addSubview: self.view to add
I want to determine if the mouse click in it.
How do I do?
Thank you.
NSImage *Image = [NSImage imageNamed:#"oneimage.jpg"];
NSImageView *ImageView = [[NSImageView alloc] init];
[ImageView setImage:Image];
[self.window addSubview:ImageView];
[ImageView_IconToAdd setAcceptsTouchEvents:YES];
[ImageView_IconToAdd setWantsRestingTouches:YES];
-(void)mouseDragged:(NSEvent *)theEvent {
id clickedObject = [self hitTest:[theEvent locationInWindow]];
if ([clickedObject isKindOfClass:[NSImageView class]]) {
NSLog(#"Clicked an ImageView");
} else if ([clickedObject isKindOfClass:[NSView class]]) {
NSLog(#"Clicked a WebView");
}
}
But error:
No visible #interface for 'WindowImage' declares the selector 'hitTest:'
And can't get Object!
is there a way to hide the flip camera button inside the UIImagePickerController?
thanks for reading
!^_^!
I ended up using a custom subclass of UIImagePickerController to fix this (and other) issues:
#import "SMImagePickerController.h"
#implementation SMImagePickerController
void hideFlipButtonInSubviews(UIView *view) {
if ([[[view class] description] isEqualToString:#"CAMFlipButton"]) {
[view setHidden:YES];
} else {
for (UIView *subview in [view subviews]) {
hideFlipButtonInSubviews(subview);
}
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
hideFlipButtonInSubviews(self.view);
}
#end
You should be able to create an empty button inside an overlayview that you float on top of the flip camera button. I hacked the code below to test and it seemed to work. Give it a try.
UIView *cameraOverlayView = [[UIView alloc] initWithFrame:CGRectMake(screenSize.width - 100.0f, 5.0f, 100.0f, 35.0f)];
[cameraOverlayView setBackgroundColor:[UIColor blackColor]];
UIButton *emptyBlackButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 35.0f)];
[emptyBlackButton setBackgroundColor:[UIColor blackColor]];
[emptyBlackButton setEnabled:YES];
[cameraOverlayView addSubview:emptyBlackButton];
cameraUI.allowsEditing = YES;
cameraUI.showsCameraControls = YES;
cameraUI.delegate = self;
cameraUI.cameraOverlayView = cameraOverlayView;
I have a little problem with adding a subview to my UIKeyboard. I can successfully locate my keyboard and add an uiimageview to it, but unfortunately the button under the image view still can be touched. I just wanted to make it a color overlay, which would hide the unneeded keys and also make them untouchable :)
Here is my code, what am I doing wrong? The UIImageView displays correctly, but the buttons still can be tapped... :(
- (UIView *)findKeyboard {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIKeyboard.
UIView *foundKeyboard = nil;
for (UIView __strong *possibleKeyboard in [keyboardWindow subviews]) {
// iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView.
if ([[possibleKeyboard description] hasPrefix:#"<UIPeripheralHostView"]) {
possibleKeyboard = [[possibleKeyboard subviews] objectAtIndex:0];
}
if ([[possibleKeyboard description] hasPrefix:#"<UIKeyboard"]) {
foundKeyboard = possibleKeyboard;
break;
}
}
return foundKeyboard;
}
- (void)keyboardWillShow:(NSNotification *)note {
UIImageView *overlayView;
UIView *keyboardView = [self findKeyboard];
UIImage *img = [UIImage imageNamed:#"keyboardOverlay.png"];
overlayView = [[UIImageView alloc] initWithImage:img];
[overlayView setUserInteractionEnabled:NO];
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, overlayView.frame.size.width, overlayView.frame.size.height)];
newView.userInteractionEnabled = NO;
newView.multipleTouchEnabled = NO;
[newView addSubview:overlayView];
[keyboardView insertSubview:newView atIndex:40];
}
User interaction being disabled means that touches are passed straight through. Enable it, but don't have any gesture recognisers or actions, and it will swallow all touches.
My code:
- (void)viewDidLoad {
[super viewDidLoad];
CGRect rectFake = CGRectZero;
UITextField *fakeField = [[UITextField alloc] initWithFrame:rectFake];
[self.view addSubview:fakeField];
UIView *av = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 39.0)];
av.backgroundColor = [UIColor darkGrayColor];
CGRect rect = CGRectMake(200.0, 4.0, 400.0, 31.0);
UITextField *textField = [[UITextField alloc] initWithFrame:rect];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.font = [UIFont systemFontOfSize:24.0];
textField.delegate = self;
[av addSubview:textField];
fakeField.inputAccessoryView = av;
[fakeField becomeFirstResponder];
}
I tried to add
[textField becomeFirstResponder]
at the end, but it does no work.
Another problem that delegate method to hide keyboard when ENTER is pressed does not work also.
- (BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
I was facing the same challenge. Your (and my initial) approach probably don't work because the text field in the inputAccessoryView refuses to become first responder as the UITextField is not located on your screen initially.
My solution: check when the keyboard (and with that the accessory view) appear!
Step 1) Listen for the notification (make sure this code is executed before you want to receive the notification).
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(changeFirstResponder)
name:UIKeyboardDidShowNotification
object:nil];
Step 2) When the keyboard has appeared, you can set the textfield in your inputAccessoryView to become first responder:
-(void)changeFirstResponder
{
[textField becomeFirstResponder]; // will return YES;
}
I am developing a simple application which make use of full screen window.
Window contains view that contains button, image etc etc... , but when I enter in full screen with the follow lines:
NSWindow* tmp = [self window];
[tmp setStyleMask:NSBorderlessWindowMask];
[tmp setFrame:[tmp frameRectForContentRect:[[tmp screen] frame]]display:YES animate:NO];
[tmp setBackingType:NSBackingStoreBuffered];
screenRect = [[NSScreen mainScreen] frame];
int windowLevel = CGShieldingWindowLevel();
[self.window setLevel:windowLevel];
The view I put in the window doesn't resized automatically, I could make some operation for resize correctly that work, but there are a way to do that automatically?
I post all my AppController here:
-(id)init {
self = [super initWithWindowNibName:#"MainWindow"];
NSWindow* tmp = [self window];
[tmp setStyleMask:NSBorderlessWindowMask];
[tmp setFrame:[tmp frameRectForContentRect:[[tmp screen] frame]]display:YES animate:NO];
[tmp setBackingType:NSBackingStoreBuffered];
screenRect = [[NSScreen mainScreen] frame];
/**
// [[tmp standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
// [[tmp standardWindowButton:NSWindowZoomButton] setHidden:YES];
self.window = [[NSWindow alloc] initWithContentRect:screenRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO screen:[NSScreen mainScreen]];
**/
int windowLevel = CGShieldingWindowLevel();
[self.window setLevel:windowLevel];
return self;
}
// We need to be layer-backed to have subview transitions.
-(void)awakeFromNib {
[[self window] setContentSize:[topMenu frame].size];
[[[self window] contentView] addSubview:topMenu];
[topMenu enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];
[[[self window] contentView] setWantsLayer:YES];
}
- (void)dealloc
{
[super dealloc];
}
- (void)windowDidLoad
{
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
[topMenu_controller performAnimation];
return;
}
You can use the springs and struts of Interface Builder to set a view's autosizing behavior:
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/IB_UserGuide/Layout/Layout.html