OSX custom keyboard field - objective-c

I am creating an application using Unity3d platform, and I want to show native osx textfields for my osx build.
Is there way to show native text field?
I have tried to add textField to NSWindow, but it is not visible.
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 100)];
[textField setStringValue:#"VALUE"];
NSApplication * shAp = [NSApplication sharedApplication];
NSWindow *window = [shAp windows][1];
if (window != NULL)
{
NSLog(#"window found, add subview");
[[window contentView] addSubview:textField];
}

My solution for this is using child window.
I create Child Window and then add TextField as subview.
All works fine, but I should resize child window when parent window is resizing.
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 50)];
NSApplication * shAp = [NSApplication sharedApplication];
NSWindow *window = [shAp windows][1];
NSWindow *overlayWindow = [[NSWindow alloc]initWithContentRect:newRect
styleMask:NSBorderlessWindowMask
backing:window.backingType
defer:NO];
[window addChildWindow:overlayWindow ordered:NSWindowAbove];
[[overlayWindow contentView] addSubview:textView];

Related

Unable to set rightview or leftview in textfield of searchbar in ios 7

Purpose:
I want to set right view as label in searchbar's textfield
Following Code working fine in ios 6 for doing the same thing:
UISearchBar *search = [[UISearchBar alloc] init];
[search setTintColor:[UIColor grayColor]];
search.frame = CGRectMake(0, 150, 320,50);
search.delegate = self;
UITextField *searchField=[search.subviews objectAtIndex:1];//Changed this line in ios 7
searchField.backgroundColor=[UIColor redColor];
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
label.text=#"Hello";
label.textColor=[UIColor greenColor];
searchField.rightView = label;
searchField.rightViewMode = UITextFieldViewModeAlways;
[self addSubView:search];
When i have Run the same code in ios 7(with xcode 7.0.2 fully updated), It was giving me error, after googling i got that hiearchy of searchbar to textfield has been changed, so i have modified my code as:
replaced commented line in above code with:
UITextField *searchField=[((UIView *)[search.subviews objectAtIndex:0]).subviews lastObject];
after doing this, it is not giving me any error(also checked the logs by printing the description of textfield and everything is working good), when i run it, it gives textfield with red background but the rightView's label is not shown to me. Now, can anyone help me how to show this rightview.
If you want to do this programatically then you have to declare UISearchBar object in your .h file.
UISearchBar *searchBar;
And in your .m file you can code like:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
searchBar = [[UISearchBar alloc] init];
[searchBar setTintColor:[UIColor grayColor]];
searchBar.frame = CGRectMake(0, 150, 320,50);
searchBar.delegate = self;
[self.view addSubview:searchBar];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UITextField *searchField;
if ([[[UIDevice currentDevice] systemVersion] floatValue]<7.0)
searchField=[searchBar.subviews objectAtIndex:1];
else
searchField=[((UIView *)[searchBar.subviews objectAtIndex:0]).subviews lastObject];
searchField.backgroundColor=[UIColor redColor];
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
label.text=#"Hello";
label.textColor=[UIColor greenColor];
searchField.rightView = label;
searchField.rightViewMode = UITextFieldViewModeAlways;
}
I think this will work for both iOS7 and prior versions of iOS7.
First of all, your approach is not good and not maintainable across iOS versions.
I think that initialization of UISearchBarTextField's right view is taking place after you set your custom view to it's rightView property. You will see correct result if you set searchField.rightView in viewDidAppear method:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UITextField *searchField=[((UIView *)[_searchBar.subviews objectAtIndex:0]).subviews lastObject];
UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
label.text=#"Hello";
label.textColor=[UIColor greenColor];
searchField.rightView = label;
searchField.rightViewMode = UITextFieldViewModeAlways;
}
I've tested it on iOS 7 simulator and it works.
You have to get the text field first.
No need to index subviews to get text field or bar button.
You can directly get the text field and bar button
In swift
let textField = searchBar.valueForKey("searchField") as? UITextField
let cancelBarButton = searchBar.valueForKey("cancelBarButtonItem") as? UIBarButtonItem
In Objective-C
UITextField *textField = [searchBar valueForKey:#"searchField"]:
UIBarButtonItem *cancelBarButton = [searchBar valueForKey:#"cancelBarButtonItem"]:
Then you can set the left view and right view with
textField.leftView = yourView
textField.rightView = yourView

How to draw an fullscreen overlay and text+text field over it?

Is there a way to draw fullscreen overlay, and then draw a label + textfield over it?
What I already did:
When user clicks button, screen should be covered by overlay.
in the AppDelegate.m button action method I wrote:
NSRect frame = [[NSScreen mainScreen] frame];
self.mainWindow = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
[self.mainWindow setAcceptsMouseMovedEvents:YES];
[self.mainWindow setOpaque:NO];
[self.mainWindow setLevel:CGShieldingWindowLevel()];
[self.mainWindow setBackgroundColor:[NSColor colorWithDeviceRed:0.0 green:0.0 blue:0.0 alpha:0.7]];
[self.mainWindow orderFrontRegardless];
NSApplicationPresentationOptions options = NSApplicationPresentationDisableProcessSwitching + NSApplicationPresentationHideDock + NSApplicationPresentationDisableForceQuit + NSApplicationPresentationDisableSessionTermination + NSApplicationPresentationDisableHideApplication;
[NSApp setPresentationOptions:options];
It's working nice, but without any animations & I really don't know how to draw objects (labels/textfields) over it?
Either, should I move this method into another class?
as for animation, there are many ways.. Id do
mainWindow.alphaValue = 0;
[mainWindow orderFrontRegardless];
[[mainWindow animator] setAlphaValue:1.0];
as for the label, just add a NSTextField with a HUGE NSFont, as a subview
NSTextField *label = ...
[[mainWindow contentView] addSubview:label];
p.s. just like with the label, you can add any other views :)

Touch on ImageView to another ViewController

I have 2 ViewControllers and I create one UIImageView to show like Splash Screen on IPhone. I write it in TestAppDelegate.m :
====================
splashScreen = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
splashScreen.image = [UIImage imageNamed:#"Default.png"];
[self.window addSubview:splashScreen];
sleep(6);
[splashScreen removeFromSuperview];
====================
My question is,
if I touch on this imageview I will go to 2nd ViewController.
else after time sleep, automatically to 1st ViewController.
So, it's possible to do that ?
Do this:
Add UIGestureRecognizerDelegate in appDelegate.h file.
#interface AppDelegate : UIResponder <UIApplicationDelegate,UIGestureRecognizerDelegate>
Now
splashScreen = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
splashScreen.userInteractionEnabled = YES;
splashScreen.image = [UIImage imageNamed:#"Default.png"];
UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 1;
tapRecognizer.delegate = self;
[splashScreen addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
[self.window addSubview:splashScreen];
sleep(6);
[splashScreen removeFromSuperview];
//add ViewController1 here
ViewController1 *objViewController1 = [[ViewController1 alloc]initWithNibName:#"ViewController1" bundle:nil];
[self.window addSubview:objViewController1.view];
Now handler will be called when tapped on splash screen
- (void)handleTap:(UITapGestureRecognizer*)recognizer
{
// Do Your thing.
if (recognizer.state == UIGestureRecognizerStateEnded)
{
[splashScreen removeFromSuperview]; //edited here
ViewController2 *objViewController2 = [[ViewController2 alloc]initWithNibName:#"ViewController2" bundle:nil];
[self.window addSubview:objViewController2.view];
}
}
Yes. It's possible.In AppDelegate keep NSTimer.
In the selector of timer write code to push to the 1st view controller.
And put a Touch Recognizer on the imageview and on the touch event write code to push to the 2nd View Controller.

On view hierarchy, clarification needed

In this code example, i am trying to produce the following view hierarchy
Window -> background image -> scroll view -> text view
All i see however is
Window -> background image
What am i missing please?
-(void) viewWillAppear:(BOOL)animated {
UIScrollView *scrollWindow = [[UIScrollView alloc]
initWithFrame:CGRectMake(30, 30, 440, 212)];
UITextView *scrollableText = [[UITextView alloc] init];
[scrollableText setEditable:NO];
[scrollableText setText:#"Why, hello there"];
[scrollWindow addSubview:scrollableText];
UIImage *backgroundImage = [[UIImage alloc] initWithCGImage:
[UIImage imageNamed:#"about_bg.png"].CGImage];
UIImageView *backgroundView = [[UIImageView alloc]
initWithImage:backgroundImage];
[backgroundView addSubview:scrollWindow];
[[self view] addSubview:backgroundView];
}
Andrew is right about not making the scroll view a subview of the background UIImageView view. But the scroll view is invisible. Only its content (scrollableText) will show. And you haven't set scrollableText's frame, so it's effectively invisible too. Init like so:
[scrollableText setEditable:NO];
[scrollableText setText:#"Why, hello there"];
[scrollableText setFrame:CGRectMake(0, 0, 100, 100)];
And you should see it.
What you need is this hierarchy:
Window
background image view
scroll view
text view
Try adding two subviews to your window, not shove them all as subviews into each other.''-
- (void) viewWillAppear:(BOOL)animated {
UIScrollView *scrollWindow = [[UIScrollView alloc] initWithFrame:CGRectMake(30, 30, 440, 212)];
UITextView *scrollableText = [[UITextView alloc] init];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"about_bg.png"]];
scrollableText.editable = NO;
scrollableText.text = #"Why, hello there";
[scrollWindow addSubview:scrollableText];
[self.view addSubview:backgroundView];
[self.view addSubview:scrollWindow];
}

How do I create a Cocoa window programmatically?

My Cocoa app needs some small dynamically generated windows. How can I programmatically create Cocoa windows at runtime?
This is my non-working attempt so far. I see no result whatsoever.
NSRect frame = NSMakeRect(0, 0, 200, 200);
NSUInteger styleMask = NSBorderlessWindowMask;
NSRect rect = [NSWindow contentRectForFrameRect:frame styleMask:styleMask];
NSWindow * window = [[NSWindow alloc] initWithContentRect:rect styleMask:styleMask backing: NSBackingStoreRetained defer:false];
[window setBackgroundColor:[NSColor blueColor]];
[window display];
The problem is that you don't want to call display, you want to call either makeKeyAndOrderFront or orderFront depending on whether or not you want the window to become the key window. You should also probably use NSBackingStoreBuffered.
This code will create your borderless, blue window at the bottom left of the screen:
NSRect frame = NSMakeRect(0, 0, 200, 200);
NSWindow* window = [[[NSWindow alloc] initWithContentRect:frame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO] autorelease];
[window setBackgroundColor:[NSColor blueColor]];
[window makeKeyAndOrderFront:NSApp];
//Don't forget to assign window to a strong/retaining property!
//Under ARC, not doing so will cause it to disappear immediately;
// without ARC, the window will be leaked.
You can make the sender for makeKeyAndOrderFront or orderFront whatever is appropriate for your situation.
A side note, if you want to programatically instantiate the application without a main nib, in the main.m file / you can instantiate the AppDelegate as below. Then in your apps Supporting Files / YourApp.plist Main nib base file / MainWindow.xib delete this entry. Then use Jason Coco's approach to attach the window in your AppDelegates init method.
#import "AppDelegate.h":
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[NSApp setDelegate:appDelegate];
[NSApp run];
[pool release];
return 0;
}
Try
[window makeKeyAndOrderFront:self];
instead of
[window display];
Is that what you're aiming for?
Translating the top rated answer to modern swift (5) gives you something akin to this:
var mainWindow: NSWindow!
...
mainWindow = NSWindow(
contentRect: NSMakeRect(0, 0, 200, 200),
styleMask: [.titled, .resizable, .miniaturizable, .closable],
backing: .buffered,
defer: false)
mainWindow.backgroundColor = .blue
mainWindow.makeKeyAndOrderFront(mainWindow)
This is what I've come up with myself:
NSRect frame = NSMakeRect(100, 100, 200, 200);
NSUInteger styleMask = NSBorderlessWindowMask;
NSRect rect = [NSWindow contentRectForFrameRect:frame styleMask:styleMask];
NSWindow * window = [[NSWindow alloc] initWithContentRect:rect styleMask:styleMask backing: NSBackingStoreBuffered defer:false];
[window setBackgroundColor:[NSColor blueColor]];
[window makeKeyAndOrderFront: window];
This displays a blue window. I hope this is the optimal approach.