Anyone know how to slide in a UIDatePicker like keyboard? - objective-c

Does anyone know how to slide in a UIDatePicker with a Done button like the keyboard control? If so, can you share some sample code on how. Thanks

I suggest you use a UIViewController, and show it modally.
Create UIViewController and setup the view with OK-button in Interface Builder, as you would for any view controller.
And display it using:
- (void)presentModalViewController:(UIViewController *)modalViewController
animated:(BOOL)animated
You can set the root views background to clear if you want it transparent. And optionaly animate it to cemi-transparent black when the transition has finished. Something like this would work:
- (void)viewDidAppear:(BOOL)animated {
if (animated) [UIView beginAnimations:#"fadeDark" context:NULL];
self.view.backgroundColor = [UIColor colorWithWithe:0.0f alpha:0.5f];
if (animated) [UIView commitAnimations];
}

1.create a subclass of the UIButton class
2.redeclare inputview as read-write
#property (nonatomic, strong, readwrite) UIView *inputView;
3.set canBecomeFirstResponder to YES
- (BOOL)canBecomeFirstResponder {
return YES;
}
4.set inputview as datepicker
self.inputView = self.datePicker;
5.set UIResponder to firstResponder when you want
[self becomeFirstResponder];
5.you can see datepicker slide in like keyboard

Related

Creating Round NSButtons for insertion into NSToolbar

For a personal project, I'm currently trying to replicate the visual stylings of the toolbar in Automator for OS X. I have tried just about everything to get my NSButtons inside of the NSToolbar to look visually similar, but can't seem to figure out the delicate UI components to figure it out, so I'm turning to the brilliant minds on Stack Overflow.
What I'm trying to do: I'm trying to copy the visual stylings of the Automator toolbar buttons:
The Setup: Currently I have tiff images for active button state, inactive button state, and pressed button state. I want to use these images as the background for the NSButtonCell. Right now, I've subclassed NSButtonCell (code below), and set the NSButtonCell class to be TFToolbarButtonCell in the XIB file in Interface Builder. In the subclass of NSButtonCell, I'm overriding -drawWithFrame:inView to draw the appropriate state image in the frame; I'm also overriding -highlight:withFrame:inView to draw the pressed image when the button is clicked.
Any direction into what I might be doing wrong here would be greatly appreciated!
TFToolbarButtonCell.h
#import <Cocoa/Cocoa.h>
#interface TFToolbarButtonCell : NSButtonCell
#property (nonatomic, strong) NSImage *onImage;
#property (nonatomic, strong) NSImage *offImage;
#property (nonatomic, strong) NSImage *highlightImage;
#end
TFToolbarButtonCell.m
#import "TFToolbarButtonCell.h"
#implementation TFToolbarButtonCell
- (id)init
{
self = [super init];
if(self) {
//initialize here
}
return self;
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
if([self state]){
[self.onImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
} else {
[self.offImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
}
- (void)highlight:(BOOL)flag withFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
if(flag){
[self.highlightImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
}
#end
I think you can accomplish what you want by subclassing NSButton and implementing
- (void)mouseDown:(NSEvent *)theEvent
- (void)mouseUp:(NSEvent *)theEvent
and your own method to set the inactive state.
These methods would call
- (void)setImage:(NSImage *)anImage
To change from active to pressed to inactive states using the different images.
You also have to uncheck "Bordered" in Interface Builder on your NSButton to stop the button background from showing.
Also, calling
- (void)setEnabled:(BOOL)enabled
on the NSToolbarItem will change the palette label to active/inactive (grey the text below the button).

Make UITextView scroll action hide a UILabel

Basically, what I want to do is detect when a user scrolls inside a text view, and then hide a label (Smoothly fade out, if possible). (The label indicates to scroll to view the rest of the text, but I don't want it to still show after the user has done so.)
If you could include in your answer the code used in the h/m files, it would be greatly appreciated.
Updated code for future reference:
.h
#interface myViewController : UIViewController
#property(nonatomic,retain) IBOutlet UILabel *label;
.m
#synthesize label;
- (void)scrollViewDidScroll:(UIScrollView *)textView
{
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0;
}];
}
Then make sure to set the UITextView delegate to self.
You can use UIScrollView's delegate method – scrollViewDidScroll: to detect that the user has scrolled, and fade out your label with a UIView animation block, like so:
[UIView animateWithDuration:1.0 animations:^{
label.alpha = 0
}];

NSPopover color

Is there any way to color NSPopover? Ive seen apps like facetab etc that have cool colors and resizeable popovers, how is this done?
Ay guides, hints?
Thanks.
Set popover.contentViewController.view as a subclass of NSView with a custom background drawing (i.e. override drawRect: and fill a rect with your custom background color).
Then set the popover.appearance = NSPopoverAppearanceHUD to remove the default border around the view.
Note that there will still be a very thin border around the view, so if you want to remove it completely, you may want to use MAAttachedWindow or a similar solution.
In Swift 4:
Go to File->New File->Cocoa Class
Name your class. eg. PopColor. Make sure it is a subclass of NSView
Set the contents of the file to:
import Cocoa
class PopoverContentView:NSView {
var backgroundView:PopoverBackgroundView?
override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
if let frameView = self.window?.contentView?.superview {
if backgroundView == nil {
backgroundView = PopoverBackgroundView(frame: frameView.bounds)
backgroundView!.autoresizingMask = NSView.AutoresizingMask([.width, .height]);
frameView.addSubview(backgroundView!, positioned: NSWindow.OrderingMode.below, relativeTo: frameView)
}
}
}
}
class PopoverBackgroundView:NSView {
override func draw(_ dirtyRect: NSRect) {
NSColor.green.set()
self.bounds.fill()
}
}
In your storyboard, select the view which has your popover content and go to the Identity Inspector
Set the Class to PopoverContentView
Your popover and its triangle will now be green.
You can use MAAttachedWindow instead.
You can subclass NSView and set it as the NSPopover's view controller's view.
Yes and no. Unfortunately NSPopover isn't designed to be customisable. You can use some simple hacks for adding additional background view behind contentViewController's view and colorise or customise it as you want. In this case, you can get the customisable background that will be masked the same as generic NSPopover border and tail.
For more details you can take a look at the code of NSPopover+MISSINGBackgroundView category that implements this approach or just use this piece of code as CocoaPod library.
The complete code to change the color of NSPopover including the triangle is here:
I assume people have hooked the popover outlets and methods
#import "AppDelegate.h"
#interface MyPopoverBackgroundView : NSView
#end
#implementation MyPopoverBackgroundView
-(void)drawRect:(NSRect)dirtyRect
{
[[NSColor redColor] set];
NSRectFill(self.bounds);
}
#end
//===============================================================================================
#interface MyPopView : NSView
#end
#implementation MyPopView
-(void)viewDidMoveToWindow{
NSView *aFrameView = [[self.window contentView] superview];
MyPopoverBackgroundView * aBGView =[[MyPopoverBackgroundView alloc] initWithFrame:aFrameView.bounds];
aBGView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[aFrameView addSubview:aBGView positioned:NSWindowBelow relativeTo:aFrameView];
[super viewDidMoveToWindow];
}
#end
//-----------------------------------------------------------------------------------------
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
//close when clicked outside
[self.popover setBehavior:NSPopoverBehaviorTransient];
//change its color
MyPopView *myPopview = [MyPopView new];
[self.popover.contentViewController.view addSubview:myPopview];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (IBAction)closePopover:(id)sender {
[self.popover close];
}
- (IBAction)showPopover:(id)sender {
[self.popover showRelativeToRect:[sender bounds]
ofView:sender
preferredEdge:NSMaxYEdge];
}
#end
This is what I did to change the popover color.
Assuming that you have properly defined your NSPopover:
//AppController.h
#import <Foundation/Foundation.h>
#interface AppController : NSObject
#property (weak) IBOutlet NSPopover errorPopover;
// whatever else you have ...
#end
//AppController.m
#import "AppController.h"
#implementation AppController
#synthesize errorPopover = _errorPopover;
// whatever else you have ...
-(IBAction)doSomethingThatCallsPopover:(id)sender {
_errorPopover.appearance = NSPopoverAppearanceHUD; //set color of error popup
[[self errorPopover] showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxXEdge];
}
#end
NSPopover Class Reference - I really wish they would provide usage code in the developer docs.

How can I use a single UIToolbar with multiple different UIViewControllers?

I have a simple app with two basic screens, a UIMapView and a UITableView. I'd like to have a toolbar at the bottom with a couple of buttons and a UISegmentedControl with two segments: "Map" and "Table". (The layout is similar to the Google Maps app that ships with the iPhone.) How can I keep the same toolbar while presenting either the UIMapView (with a UIMapViewController) or the UITableView (with a UITableViewController) when the user switches back and forth on the segmented control? Of course, I can just create an identical toolbar for each of the two different views and display them separately, but is there a better way?
Write a UIViewController that manages your 2 VC's and transitions between the MKMapView and UITableView in response to the segmented control.
First set up the nib for this new VC in Interface Builder: add an UISegementedControl and a simple UIView (contentView).
The interface file contains references to the UI Elements and to the 2 VC's + an action to respond to the segmented control:
//
// MapAndTableViewController.h
//
#import <UIKit/UIKit.h>
#import "MyMapViewController.h"
#import "MyTableViewController.h"
#interface MapAndTableViewController : UIViewController {
IBOutlet UISegmentedControl* segmentedControl;
IBOutlet UIView* contentView;
UIViewController* firstVC;
UIViewController* secondVC;
}
-(IBAction) valueChanged:(UISegmentedControl*) sender;
#end
Implementation:
//
// MapAndTableViewController.m
//
#import "MapAndTableViewController.h"
#implementation MapAndTableViewController
-(IBAction) valueChanged:(UISegmentedControl*) sender {
if (sender.selectedSegmentIndex == 0) {
[UIView transitionFromView:[contentView.subviews lastObject] toView:firstVC.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
}
if (sender.selectedSegmentIndex == 1) {
[UIView transitionFromView:[contentView.subviews lastObject] toView:secondVC.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
}
}
-(void)awakeFromNib {
firstVC = [[MyMapViewController alloc] initWithNibName:#"MyMapViewController" bundle:nil];
secondVC = [[MyTableViewController alloc] initWithNibName:#"MyTableViewController" bundle:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
[contentView addSubview:firstVC.view];
}
- (void)dealloc {
[firstVC release];
[secondVC release];
[super dealloc];
}
#end
In the valueChanged method you replace the current view and animate the transition.
Note that the views firstVC.view and secondVC.view are created on first access of the view-property of each VC.
you could use a single view controller, and add all of the views(UIMapView, UITableView, etc) to your view and simply show/hide the correct views upon clicking the segmented control
with such a simple app without many views, you shouldn't have a messy/clustered view controller file and can easily show/hide these 2 views.
perhaps use an animation between switching between views so it looks nice

NSScrollView doesn't show scrollbars even although the content is large enough

I have this class:
Header:
#interface vcMain : NSWindowController {
IBOutlet NSView *scroll;
}
#property (retain) IBOutlet NSView *scroll;
-(IBAction)test:(id)sender;
#end
Source:
#implementation vcMain
#synthesize scroll;
-(IBAction)test:(id)sender {
vItem *item = [[vItem alloc] initWithNibName:#"vItem" bundle:nil];
NSView *view = [item view];
[view setFrame:NSMakeRect(0, 0, 300, 600)];
[view setAutoresizingMask:( NSViewHeightSizable) ];
[scroll addSubview:view];
}
#end
*scroll is a Custom View in a Bordered Scroll View in the Content View of a Window.
vItem is a ViewController subclass with some things on it to identify its position.
Problem: When resizing my vcMain from the default 300x600 to 150x300, I don't see any scrollbars.
What am I doing wrong?
Tom
Solved
It was simple, actually. Resizing the view apparently also resized the subview so it wasn't neccessary to show the scrollbars - however, as the elements in the subview didn't move, I didn't notice that the subview was resizing.
Solved by correcting the resizing of the view.